mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 12:44:45 +02:00
Merge pull request #1181 from dgarske/cert_serial
Certificate serial number enhancements
This commit is contained in:
@@ -6388,31 +6388,30 @@ WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
|
|||||||
|
|
||||||
WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
|
WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int i = 0;
|
||||||
|
int snSzInt = (int)snSz;
|
||||||
WOLFSSL_ENTER("SetSerialNumber");
|
|
||||||
|
|
||||||
if (sn == NULL || output == NULL)
|
if (sn == NULL || output == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (snSz <= EXTERNAL_SERIAL_SIZE) {
|
/* remove leading zeros */
|
||||||
output[0] = ASN_INTEGER;
|
while (snSzInt > 0 && sn[0] == 0) {
|
||||||
/* The serial number is always positive. When encoding the
|
snSzInt--;
|
||||||
* INTEGER, if the MSB is 1, add a padding zero to keep the
|
sn++;
|
||||||
* number positive. */
|
|
||||||
if (sn[0] & 0x80) {
|
|
||||||
output[1] = (byte)snSz + 1;
|
|
||||||
output[2] = 0;
|
|
||||||
XMEMCPY(&output[3], sn, snSz);
|
|
||||||
result = snSz + 3;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
output[1] = (byte)snSz;
|
/* encode ASN Integer, with length and value */
|
||||||
XMEMCPY(&output[2], sn, snSz);
|
output[i++] = ASN_INTEGER;
|
||||||
result = snSz + 2;
|
i += SetLength(snSzInt, &output[i]);
|
||||||
}
|
XMEMCPY(&output[i], sn, snSzInt);
|
||||||
}
|
|
||||||
return result;
|
/* ensure positive (MSB not set) */
|
||||||
|
output[i] &= ~0x80;
|
||||||
|
|
||||||
|
/* compute final length */
|
||||||
|
i += snSzInt;
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
|
WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
|
||||||
@@ -6971,6 +6970,7 @@ int wc_InitCert(Cert* cert)
|
|||||||
#endif
|
#endif
|
||||||
cert->keyType = RSA_KEY;
|
cert->keyType = RSA_KEY;
|
||||||
XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
|
XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE);
|
||||||
|
cert->serialSz = 0;
|
||||||
|
|
||||||
cert->issuer.country[0] = '\0';
|
cert->issuer.country[0] = '\0';
|
||||||
cert->issuer.countryEnc = CTC_PRINTABLE;
|
cert->issuer.countryEnc = CTC_PRINTABLE;
|
||||||
@@ -7081,18 +7081,6 @@ static word32 SetUTF8String(word32 len, byte* output)
|
|||||||
#endif /* WOLFSSL_CERT_REQ */
|
#endif /* WOLFSSL_CERT_REQ */
|
||||||
|
|
||||||
|
|
||||||
/* Write a serial number to output */
|
|
||||||
static int SetSerial(const byte* serial, byte* output)
|
|
||||||
{
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
output[length++] = ASN_INTEGER;
|
|
||||||
length += SetLength(CTC_SERIAL_SIZE, &output[length]);
|
|
||||||
XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE);
|
|
||||||
|
|
||||||
return length + CTC_SERIAL_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) */
|
#endif /* defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) */
|
||||||
#if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
|
#if defined(HAVE_ECC) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
|
||||||
|
|
||||||
@@ -8187,13 +8175,20 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
|||||||
/* version */
|
/* version */
|
||||||
der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
|
der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
|
||||||
|
|
||||||
/* serial number */
|
/* serial number (must be positive) */
|
||||||
ret = wc_RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE);
|
if (cert->serialSz == 0) {
|
||||||
|
/* generate random serial */
|
||||||
|
cert->serialSz = CTC_SERIAL_SIZE;
|
||||||
|
ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
cert->serial[0] = 0x01; /* ensure positive */
|
else if (cert->serialSz > CTC_SERIAL_SIZE) {
|
||||||
der->serialSz = SetSerial(cert->serial, der->serial);
|
cert->serialSz = CTC_SERIAL_SIZE;
|
||||||
|
}
|
||||||
|
der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial);
|
||||||
|
if (der->serialSz < 0)
|
||||||
|
return der->serialSz;
|
||||||
|
|
||||||
/* signature algo */
|
/* signature algo */
|
||||||
der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
|
der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
|
||||||
@@ -11085,8 +11080,8 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
|
|||||||
byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
|
byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
|
||||||
byte snArray[MAX_SN_SZ];
|
byte snArray[MAX_SN_SZ];
|
||||||
byte extArray[MAX_OCSP_EXT_SZ];
|
byte extArray[MAX_OCSP_EXT_SZ];
|
||||||
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
|
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
|
||||||
int i;
|
int i, snSz;
|
||||||
|
|
||||||
WOLFSSL_ENTER("EncodeOcspRequest");
|
WOLFSSL_ENTER("EncodeOcspRequest");
|
||||||
|
|
||||||
@@ -11096,11 +11091,17 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
|
|||||||
algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
|
algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (req->serialSz > EXTERNAL_SERIAL_SIZE)
|
||||||
|
req->serialSz = EXTERNAL_SERIAL_SIZE;
|
||||||
|
|
||||||
issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray);
|
issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray);
|
||||||
issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray);
|
issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray);
|
||||||
snSz = SetSerialNumber(req->serial, req->serialSz, snArray);
|
snSz = SetSerialNumber(req->serial, req->serialSz, snArray);
|
||||||
extSz = 0;
|
extSz = 0;
|
||||||
|
|
||||||
|
if (snSz < 0)
|
||||||
|
return snSz;
|
||||||
|
|
||||||
if (req->nonceSz) {
|
if (req->nonceSz) {
|
||||||
/* TLS Extensions use this function too - put extensions after
|
/* TLS Extensions use this function too - put extensions after
|
||||||
* ASN.1: Context Specific [2].
|
* ASN.1: Context Specific [2].
|
||||||
|
@@ -8202,6 +8202,7 @@ int rsa_test(void)
|
|||||||
/* self signed */
|
/* self signed */
|
||||||
{
|
{
|
||||||
Cert myCert;
|
Cert myCert;
|
||||||
|
const byte mySerial[8] = {1,2,3,4,5,6,7,8};
|
||||||
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
||||||
FILE* derFile;
|
FILE* derFile;
|
||||||
FILE* pemFile;
|
FILE* pemFile;
|
||||||
@@ -8232,6 +8233,8 @@ int rsa_test(void)
|
|||||||
XSTRNCPY(myCert.subject.unit, "Development", CTC_NAME_SIZE);
|
XSTRNCPY(myCert.subject.unit, "Development", CTC_NAME_SIZE);
|
||||||
XSTRNCPY(myCert.subject.commonName, "www.yassl.com", CTC_NAME_SIZE);
|
XSTRNCPY(myCert.subject.commonName, "www.yassl.com", CTC_NAME_SIZE);
|
||||||
XSTRNCPY(myCert.subject.email, "info@yassl.com", CTC_NAME_SIZE);
|
XSTRNCPY(myCert.subject.email, "info@yassl.com", CTC_NAME_SIZE);
|
||||||
|
XMEMCPY(myCert.serial, mySerial, sizeof(mySerial));
|
||||||
|
myCert.serialSz = (int)sizeof(mySerial);
|
||||||
myCert.isCA = 1;
|
myCert.isCA = 1;
|
||||||
myCert.sigType = CTC_SHA256wRSA;
|
myCert.sigType = CTC_SHA256wRSA;
|
||||||
|
|
||||||
|
@@ -99,7 +99,7 @@ enum Ctc_Misc {
|
|||||||
CTC_NAME_SIZE = 64,
|
CTC_NAME_SIZE = 64,
|
||||||
CTC_DATE_SIZE = 32,
|
CTC_DATE_SIZE = 32,
|
||||||
CTC_MAX_ALT_SIZE = 16384, /* may be huge */
|
CTC_MAX_ALT_SIZE = 16384, /* may be huge */
|
||||||
CTC_SERIAL_SIZE = 8,
|
CTC_SERIAL_SIZE = 16,
|
||||||
#ifdef WOLFSSL_CERT_EXT
|
#ifdef WOLFSSL_CERT_EXT
|
||||||
/* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum
|
/* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum
|
||||||
* We support only hash */
|
* We support only hash */
|
||||||
@@ -136,6 +136,7 @@ typedef struct CertName {
|
|||||||
typedef struct Cert {
|
typedef struct Cert {
|
||||||
int version; /* x509 version */
|
int version; /* x509 version */
|
||||||
byte serial[CTC_SERIAL_SIZE]; /* serial number */
|
byte serial[CTC_SERIAL_SIZE]; /* serial number */
|
||||||
|
int serialSz; /* serial size */
|
||||||
int sigType; /* signature algo type */
|
int sigType; /* signature algo type */
|
||||||
CertName issuer; /* issuer info */
|
CertName issuer; /* issuer info */
|
||||||
int daysValid; /* validity days */
|
int daysValid; /* validity days */
|
||||||
|
Reference in New Issue
Block a user