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) 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;
XMEMCPY(&output[2], sn, snSz);
result = snSz + 2;
}
} }
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, 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) {
if (ret != 0) /* generate random serial */
return ret; cert->serialSz = CTC_SERIAL_SIZE;
ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
cert->serial[0] = 0x01; /* ensure positive */ if (ret != 0)
der->serialSz = SetSerial(cert->serial, der->serial); 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 */ /* 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].

View File

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

View File

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