mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 03:34:39 +02:00
Enhancement to allow a serial number to be customized via Cert.serial
and Cert.serialSz
for cert request or generation. Fix to make sure serial number is always postive and has no leading zeros. Increase the size of the certificate serial number to 20 bytes.
This commit is contained in:
@@ -6370,31 +6370,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,
|
||||
@@ -6953,6 +6952,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;
|
||||
@@ -7063,18 +7063,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))
|
||||
|
||||
@@ -8169,13 +8157,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);
|
||||
@@ -11067,8 +11062,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");
|
||||
|
||||
@@ -11078,11 +11073,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].
|
||||
|
@@ -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 = 20,
|
||||
#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 */
|
||||
|
Reference in New Issue
Block a user