Merge pull request #1181 from dgarske/cert_serial

Certificate serial number enhancements
This commit is contained in:
toddouska
2017-10-13 09:22:11 -07:00
committed by GitHub
3 changed files with 47 additions and 42 deletions

View File

@@ -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].

View File

@@ -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;

View File

@@ -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 */