diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5f5ca7808..8942d91f6 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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) { - int result = 0; - - WOLFSSL_ENTER("SetSerialNumber"); + int i = 0; + int snSzInt = (int)snSz; if (sn == NULL || output == NULL) return BAD_FUNC_ARG; - if (snSz <= EXTERNAL_SERIAL_SIZE) { - output[0] = ASN_INTEGER; - /* The serial number is always positive. When encoding the - * INTEGER, if the MSB is 1, add a padding zero to keep the - * 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; - XMEMCPY(&output[2], sn, snSz); - result = snSz + 2; - } + /* remove leading zeros */ + while (snSzInt > 0 && sn[0] == 0) { + snSzInt--; + sn++; } - return result; + + /* encode ASN Integer, with length and value */ + output[i++] = ASN_INTEGER; + i += SetLength(snSzInt, &output[i]); + XMEMCPY(&output[i], sn, snSzInt); + + /* ensure positive (MSB not set) */ + output[i] &= ~0x80; + + /* compute final length */ + i += snSzInt; + + return i; } WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx, @@ -6971,6 +6970,7 @@ int wc_InitCert(Cert* cert) #endif cert->keyType = RSA_KEY; XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); + cert->serialSz = 0; cert->issuer.country[0] = '\0'; cert->issuer.countryEnc = CTC_PRINTABLE; @@ -7081,18 +7081,6 @@ static word32 SetUTF8String(word32 len, byte* output) #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) */ #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 */ der->versionSz = SetMyVersion(cert->version, der->version, TRUE); - /* serial number */ - ret = wc_RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); - if (ret != 0) - return ret; - - cert->serial[0] = 0x01; /* ensure positive */ - der->serialSz = SetSerial(cert->serial, der->serial); + /* serial number (must be positive) */ + if (cert->serialSz == 0) { + /* generate random serial */ + cert->serialSz = CTC_SERIAL_SIZE; + ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz); + if (ret != 0) + return ret; + } + else if (cert->serialSz > CTC_SERIAL_SIZE) { + cert->serialSz = CTC_SERIAL_SIZE; + } + der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial); + if (der->serialSz < 0) + return der->serialSz; /* signature algo */ 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 snArray[MAX_SN_SZ]; byte extArray[MAX_OCSP_EXT_SZ]; - word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; - int i; + word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz; + int i, snSz; WOLFSSL_ENTER("EncodeOcspRequest"); @@ -11096,11 +11091,17 @@ int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size) algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0); #endif + if (req->serialSz > EXTERNAL_SERIAL_SIZE) + req->serialSz = EXTERNAL_SERIAL_SIZE; + issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray); issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray); snSz = SetSerialNumber(req->serial, req->serialSz, snArray); extSz = 0; + if (snSz < 0) + return snSz; + if (req->nonceSz) { /* TLS Extensions use this function too - put extensions after * ASN.1: Context Specific [2]. diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f2e587c55..2c3ddc7aa 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8202,6 +8202,7 @@ int rsa_test(void) /* self signed */ { Cert myCert; + const byte mySerial[8] = {1,2,3,4,5,6,7,8}; #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) FILE* derFile; FILE* pemFile; @@ -8232,6 +8233,8 @@ int rsa_test(void) XSTRNCPY(myCert.subject.unit, "Development", CTC_NAME_SIZE); XSTRNCPY(myCert.subject.commonName, "www.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.sigType = CTC_SHA256wRSA; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index d9addfe97..0e428942b 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -99,7 +99,7 @@ enum Ctc_Misc { CTC_NAME_SIZE = 64, CTC_DATE_SIZE = 32, CTC_MAX_ALT_SIZE = 16384, /* may be huge */ - CTC_SERIAL_SIZE = 8, + CTC_SERIAL_SIZE = 16, #ifdef WOLFSSL_CERT_EXT /* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum * We support only hash */ @@ -136,6 +136,7 @@ typedef struct CertName { typedef struct Cert { int version; /* x509 version */ byte serial[CTC_SERIAL_SIZE]; /* serial number */ + int serialSz; /* serial size */ int sigType; /* signature algo type */ CertName issuer; /* issuer info */ int daysValid; /* validity days */