Merge pull request #3247 from JacobBarthelmeh/Compatibility-Layer

Compatiblity Layer Fixes for serial number / ASN1 time / and order of name components
This commit is contained in:
toddouska
2020-09-16 14:53:51 -07:00
committed by GitHub
7 changed files with 424 additions and 269 deletions

412
src/ssl.c
View File

@ -17790,16 +17790,24 @@ int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME* name)
byte* in, int* inOutSz)
{
WOLFSSL_ENTER("wolfSSL_X509_get_serial_number");
if (x509 == NULL || in == NULL ||
inOutSz == NULL || *inOutSz < x509->serialSz)
if (x509 == NULL || inOutSz == NULL) {
WOLFSSL_MSG("Null argument passed in");
return BAD_FUNC_ARG;
}
XMEMCPY(in, x509->serial, x509->serialSz);
if (in != NULL) {
if (*inOutSz < x509->serialSz) {
WOLFSSL_MSG("Serial buffer too small");
return BUFFER_E;
}
XMEMCPY(in, x509->serial, x509->serialSz);
}
*inOutSz = x509->serialSz;
return WOLFSSL_SUCCESS;
}
/* not an openssl compatibility function - getting for derCert */
const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz)
{
@ -37150,167 +37158,38 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
}
#if defined(WOLFSSL_CERT_GEN)
/* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
* a Cert structure.
*
* returns length of DER on success and a negative error value on failure
*/
static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
{
unsigned char* der = NULL;
int length = BAD_FUNC_ARG, ret = BAD_FUNC_ARG;
word32 idx = 0;
/* helper function for CopyX509NameToCertName()
*
* returns WOLFSSL_SUCCESS on success
*/
static int CopyX509NameEntry(char* out, int mx, WOLFSSL_X509_NAME* name,
int nid, byte* transfered)
{
int inLen = 0;
unsigned char* in = NULL;
int i;
if (nid == ASN_COUNTRY_NAME)
nid = NID_countryName;
if (nid == ASN_EMAIL_NAME)
nid = NID_emailAddress;
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
if (name->entry[i].set && name->entry[i].nid == nid) {
in = wolfSSL_ASN1_STRING_data(name->entry[i].value);
inLen = wolfSSL_ASN1_STRING_length(name->entry[i].value);
transfered[i] = 1;
break;
}
}
if (in == NULL) {
/* entry type not found */
return WOLFSSL_FAILURE;
}
if (inLen > mx) {
WOLFSSL_MSG("Name too long");
XMEMCPY(out, in, mx);
}
else {
XMEMCPY(out, in, inLen);
out[inLen] = '\0';
}
/* make sure is null terminated */
out[mx-1] = '\0';
return WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_MULTI_ATTRIB
/* Converts from NID_* value to wolfSSL value if needed */
static int ConvertNIDToWolfSSL(int nid)
{
switch (nid) {
case NID_commonName : return ASN_COMMON_NAME;
case NID_surname : return ASN_SUR_NAME;
case NID_countryName: return ASN_COUNTRY_NAME;
case NID_localityName: return ASN_LOCALITY_NAME;
case NID_stateOrProvinceName: return ASN_STATE_NAME;
case NID_organizationName: return ASN_ORG_NAME;
case NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
case NID_emailAddress: return ASN_EMAIL_NAME;
case NID_serialNumber: return ASN_SERIAL_NUMBER;
case NID_businessCategory: return ASN_BUS_CAT;
case NID_domainComponent: return ASN_DOMAIN_COMPONENT;
default:
WOLFSSL_MSG("Attribute NID not found");
return -1;
}
}
#endif /* WOLFSSL_MULTI_ATTRIB */
/* Helper function to copy cert name from a WOLFSSL_X509_NAME structure to
* a CertName structure.
*
* returns WOLFSSL_SUCCESS on success and a negative error value on failure
*/
static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
{
int idx = 0;
#ifdef WOLFSSL_MULTI_ATTRIB
int i, j = 0;
#endif
int count = 0;
const char* current;
byte transferred[MAX_NAME_ENTRIES] = {0};
if (n == NULL || cName == NULL) {
return BAD_FUNC_ARG;
}
/* initialize cert name */
cName->country[0] = '\0';
cName->countryEnc = CTC_PRINTABLE;
cName->state[0] = '\0';
cName->stateEnc = CTC_UTF8;
cName->locality[0] = '\0';
cName->localityEnc = CTC_UTF8;
cName->sur[0] = '\0';
cName->surEnc = CTC_UTF8;
cName->org[0] = '\0';
cName->orgEnc = CTC_UTF8;
cName->unit[0] = '\0';
cName->unitEnc = CTC_UTF8;
cName->commonName[0] = '\0';
cName->commonNameEnc = CTC_UTF8;
cName->serialDev[0] = '\0';
cName->serialDevEnc = CTC_PRINTABLE;
#ifdef WOLFSSL_CERT_EXT
cName->busCat[0] = '\0';
cName->busCatEnc = CTC_UTF8;
cName->joiC[0] = '\0';
cName->joiCEnc = CTC_PRINTABLE;
cName->joiSt[0] = '\0';
cName->joiStEnc = CTC_PRINTABLE;
#endif
cName->email[0] = '\0';
current = GetOneCertName(cName, idx);
while (current != NULL) {
if (CopyX509NameEntry((char*)current, CTC_NAME_SIZE, n,
GetCertNameId(idx), transferred) == SSL_SUCCESS) {
count++;
ret = wolfSSL_i2d_X509_NAME(n, &der);
if (ret > (int)sizeof(CertName) || ret < 0) {
WOLFSSL_MSG("Name conversion error");
ret = MEMORY_E;
}
idx++;
current = GetOneCertName(cName, idx);
}
#ifdef WOLFSSL_MULTI_ATTRIB
/* copy over multiple entries */
idx = wolfSSL_X509_NAME_entry_count(n);
for (i = 0; i < MAX_NAME_ENTRIES && count < idx; i++) {
/* entry is set but was not yet transferred over */
if (n->entry[i].set && transferred[i] == 0) {
unsigned char* data;
int length;
WOLFSSL_X509_NAME_ENTRY* e = &n->entry[i];
data = wolfSSL_ASN1_STRING_data(e->value);
length = wolfSSL_ASN1_STRING_length(e->value);
if (j >= CTC_MAX_ATTRIB) {
WOLFSSL_MSG("No more space left in CertName");
break;
}
cName->name[j].sz = length;
cName->name[j].type = CTC_UTF8;
cName->name[j].id = ConvertNIDToWolfSSL(e->nid);
XMEMCPY(cName->name[j].value, data, length);
j++;
count++;
if (ret > 0) {
/* strip off sequence, this gets added on certificate creation */
ret = GetSequence(der, &idx, &length, ret);
}
}
#endif /* WOLFSSL_MULTI_ATTRIB */
if (ret > 0) {
XMEMCPY(out, der + idx, length);
}
if (der != NULL)
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
return length;
}
return WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_CERT_REQ
static int ReqCertFromX509(Cert* cert, WOLFSSL_X509* req)
@ -37320,7 +37199,16 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
if (wc_InitCert(cert) != 0)
return WOLFSSL_FAILURE;
ret = CopyX509NameToCertName(&req->subject, &cert->subject);
ret = CopyX509NameToCert(&(req->subject), cert->sbjRaw);
if (ret < 0) {
WOLFSSL_MSG("REQ subject conversion error");
ret = MEMORY_E;
}
else {
ret = WOLFSSL_SUCCESS;
}
if (ret == WOLFSSL_SUCCESS) {
cert->version = req->version;
cert->isCA = req->isCa;
@ -37338,6 +37226,26 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
return ret;
}
#endif
#ifdef WOLFSSL_ALT_NAMES
/* converts WOLFSSL_AN1_TIME to Cert form, returns positive size on
* success */
static int CertDateFromX509(byte* out, int outSz, WOLFSSL_ASN1_TIME* t)
{
int sz, i;
if (t->length + 1 >= outSz) {
return BUFFER_E;
}
out[0] = t->type;
sz = SetLength(t->length - 1, out + 1) + 1; /* gen tag */
for (i = 0; i < t->length - 1; i++) {
out[sz + i] = t->data[i];
}
return t->length - 1 + sz;
}
#endif
/* convert a WOLFSSL_X509 to a Cert structure for writing out */
static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
@ -37359,31 +37267,22 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
#ifdef WOLFSSL_ALT_NAMES
if (x509->notBefore.length > 0) {
if ((x509->notBefore.length + 2) < CTC_DATE_SIZE) {
cert->beforeDate[0] = x509->notBefore.type;
cert->beforeDate[1] = x509->notBefore.length;
XMEMCPY(&cert->beforeDate[2], x509->notBefore.data,
x509->notBefore.length);
cert->beforeDateSz = x509->notBefore.length + 2;
}
else {
WOLFSSL_MSG("Not before date too large");
cert->beforeDateSz = CertDateFromX509(cert->beforeDate,
CTC_DATE_SIZE, &x509->notBefore);
if (cert->beforeDateSz <= 0){
WOLFSSL_MSG("Not before date error");
return WOLFSSL_FAILURE;
}
}
else {
cert->beforeDateSz = 0;
}
if (x509->notAfter.length > 0) {
if ((x509->notAfter.length + 2) < CTC_DATE_SIZE) {
cert->afterDate[0] = x509->notAfter.type;
cert->afterDate[1] = x509->notAfter.length;
XMEMCPY(&cert->afterDate[2], x509->notAfter.data,
x509->notAfter.length);
cert->afterDateSz = x509->notAfter.length + 2;
}
else {
WOLFSSL_MSG("Not after date too large");
cert->afterDateSz = CertDateFromX509(cert->afterDate,
CTC_DATE_SIZE, &x509->notAfter);
if (cert->afterDateSz <= 0){
WOLFSSL_MSG("Not after date error");
return WOLFSSL_FAILURE;
}
}
@ -37440,29 +37339,41 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE);
#endif
if (x509->serialSz <= CTC_SERIAL_SIZE) {
XMEMCPY(cert->serial, x509->serial, x509->serialSz);
}
else {
WOLFSSL_MSG("Serial size error");
return WOLFSSL_FAILURE;
/* set serial number */
if (x509->serialSz > 0) {
byte serial[EXTERNAL_SERIAL_SIZE];
int serialSz = EXTERNAL_SERIAL_SIZE;
ret = wolfSSL_X509_get_serial_number(x509, serial, &serialSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Serial size error");
return WOLFSSL_FAILURE;
}
XMEMCPY(cert->serial, serial, serialSz);
cert->serialSz = serialSz;
}
/* copy over Name structures */
if (x509->issuerSet)
cert->selfSigned = 0;
if ((ret = CopyX509NameToCertName(&(x509->issuer), &(cert->issuer)))
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error copying over issuer names");
WOLFSSL_LEAVE("wolfSSL_X509_to_Cert()", ret);
return WOLFSSL_FAILURE;
ret = CopyX509NameToCert(&(x509->subject), cert->sbjRaw);
if (ret < 0) {
WOLFSSL_MSG("Subject conversion error");
return MEMORY_E;
}
if ((ret = CopyX509NameToCertName(&(x509->subject), &(cert->subject)))
!= WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error copying over subject names");
WOLFSSL_LEAVE("wolfSSL_X509_to_Cert()", ret);
return WOLFSSL_FAILURE;
if (cert->selfSigned) {
XMEMCPY(cert->issRaw, cert->sbjRaw, sizeof(CertName));
}
else {
ret = CopyX509NameToCert(&(x509->issuer), cert->issRaw);
if (ret < 0) {
WOLFSSL_MSG("Issuer conversion error");
return MEMORY_E;
}
}
cert->heap = x509->heap;
@ -37632,13 +37543,26 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
ret = wc_MakeCert_ex(&cert, der, *derSz, type, key, &rng);
wc_FreeRng(&rng);
}
if (ret < 0) {
return ret;
}
if ((x509->serialSz == 0) && (cert.serialSz <= EXTERNAL_SERIAL_SIZE)) {
XMEMCPY(x509->serial, cert.serial, cert.serialSz);
x509->serialSz = cert.serialSz;
if ((ret > 0) && (x509->serialSz == 0) &&
(cert.serialSz <= EXTERNAL_SERIAL_SIZE) &&
(cert.serialSz > 0)) {
WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
if (i == NULL) {
ret = MEMORY_E;
}
else {
i->length = cert.serialSz + 2;
i->data[0] = ASN_INTEGER;
i->data[1] = cert.serialSz;
XMEMCPY(i->data + 2, cert.serial, cert.serialSz);
if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Issue setting generated serial number");
ret = EXTENSIONS_E;
}
wolfSSL_ASN1_INTEGER_free(i);
}
}
/* Dispose of the public key object. */
@ -37650,9 +37574,14 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
if (x509->pubKeyOID == ECDSAk)
wc_ecc_free(&ecc);
#endif
*derSz = ret;
return WOLFSSL_SUCCESS;
if (ret > 0) {
*derSz = ret;
return WOLFSSL_SUCCESS;
}
else {
return ret;
}
}
@ -37719,12 +37648,18 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
return ret;
}
#ifndef WC_MAX_X509_GEN
/* able to override max size until dynamic buffer created */
#define WC_MAX_X509_GEN 4096
#endif
/* returns the size of signature on success */
int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
const WOLFSSL_EVP_MD* md)
{
int ret;
byte der[4096]; /* @TODO dynamic set based on expected cert size */
byte der[WC_MAX_X509_GEN]; /* @TODO dynamic based on expected cert size */
int derSz = sizeof(der);
WOLFSSL_ENTER("wolfSSL_X509_sign");
@ -37749,53 +37684,6 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
return ret;
}
/* Converts the x509 name structure into DER format.
*
* out pointer to either a pre setup buffer or a pointer to null for
* creating a dynamic buffer. In the case that a pre-existing buffer is
* used out will be incremented the size of the DER buffer on success.
*
* returns the size of the buffer on success, or negative value with failure
*/
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
{
CertName cName;
unsigned char buf[256]; /* ASN_MAX_NAME */
int sz;
WOLFSSL_ENTER("wolfSSL_i2d_X509_NAME");
if (out == NULL || name == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(&cName, 0, sizeof(CertName));
if (CopyX509NameToCertName(name, &cName) != SSL_SUCCESS) {
WOLFSSL_MSG("Error converting x509 name to internal CertName");
return SSL_FATAL_ERROR;
}
sz = SetName(buf, sizeof(buf), &cName);
if (sz < 0) {
return sz;
}
/* using buffer passed in */
if (*out != NULL) {
XMEMCPY(*out, buf, sz);
*out += sz;
}
else {
*out = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
if (*out == NULL) {
return MEMORY_E;
}
XMEMCPY(*out, buf, sz);
}
return sz;
}
#endif /* WOLFSSL_CERT_GEN */
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
@ -48303,7 +48191,10 @@ int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
return WOLFSSL_FAILURE;
}
XMEMCPY(&x509->notAfter, t, sizeof(WOLFSSL_ASN1_TIME));
x509->notAfter.type = t->type;
x509->notAfter.length = t->length;
XMEMCPY(x509->notAfter.data, t->data, CTC_DATE_SIZE);
return WOLFSSL_SUCCESS;
}
@ -48314,7 +48205,10 @@ int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
return WOLFSSL_FAILURE;
}
XMEMCPY(&x509->notBefore, t, sizeof(WOLFSSL_ASN1_TIME));
x509->notBefore.type = t->type;
x509->notBefore.length = t->length;
XMEMCPY(x509->notBefore.data, t->data, CTC_DATE_SIZE);
return WOLFSSL_SUCCESS;
}
@ -48322,16 +48216,16 @@ int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t)
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
{
WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
if (!x509 || !s || s->dataMax >= EXTERNAL_SERIAL_SIZE)
if (!x509 || !s || s->length >= EXTERNAL_SERIAL_SIZE)
return WOLFSSL_FAILURE;
if (s->isDynamic)
XSTRNCPY((char*)x509->serial,(char*)s->data,s->dataMax);
else
XSTRNCPY((char*)x509->serial,(char*)s->intData,s->dataMax);
x509->serial[s->dataMax] = 0;
x509->serialSz = s->dataMax;
/* WOLFSSL_ASN1_INTEGER has type | size | data */
if (s->length < 3) {
return WOLFSSL_FAILURE;
}
XMEMCPY(x509->serial, s->data + 2, s->length - 2);
x509->serialSz = s->length - 2;
x509->serial[s->length] = 0;
return WOLFSSL_SUCCESS;
}

View File

@ -27731,20 +27731,26 @@ static void test_wolfSSL_X509_sign(void)
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
int ret;
char *caSubject;
X509_NAME *name;
X509 *x509;
X509 *x509, *ca;
DecodedCert dCert;
EVP_PKEY *pub;
EVP_PKEY *priv;
#if defined(USE_CERT_BUFFERS_1024)
const unsigned char* rsaPriv = client_key_der_1024;
const unsigned char* rsaPub = client_keypub_der_1024;
const unsigned char* certIssuer = client_cert_der_1024;
long clientKeySz = (long)sizeof_client_key_der_1024;
long clientPubKeySz = (long)sizeof_client_keypub_der_1024;
long certIssuerSz = (long)sizeof_client_cert_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
const unsigned char* rsaPriv = client_key_der_2048;
const unsigned char* rsaPub = client_keypub_der_2048;
const unsigned char* certIssuer = client_cert_der_2048;
long clientKeySz = (long)sizeof_client_key_der_2048;
long clientPubKeySz = (long)sizeof_client_keypub_der_2048;
long certIssuerSz = (long)sizeof_client_cert_der_2048;
#endif
byte sn[16];
int snSz = sizeof(sn);
@ -27769,6 +27775,7 @@ static void test_wolfSSL_X509_sign(void)
AssertIntNE(X509_set_version(x509, 2L), 0);
/* Set subject name, add pubkey, and sign certificate */
AssertIntEQ(X509_set_subject_name(x509, name), SSL_SUCCESS);
X509_NAME_free(name);
AssertIntEQ(X509_set_pubkey(x509, pub), SSL_SUCCESS);
#ifdef WOLFSSL_ALT_NAMES
/* Add some subject alt names */
@ -27817,7 +27824,7 @@ static void test_wolfSSL_X509_sign(void)
}
XFCLOSE(tmpFile);
#endif
/* Variation in size depends on ASN.1 encoding when MSB is set */
#ifndef WOLFSSL_ALT_NAMES
/* Valid case - size should be 798-797 with 16 byte serial number */
@ -27829,6 +27836,35 @@ static void test_wolfSSL_X509_sign(void)
/* Valid case - size should be 926-927 with 16 byte serial number */
AssertTrue((ret == 910 + snSz) || (ret == 911 + snSz));
#endif
/* check that issuer name is as expected after signature */
InitDecodedCert(&dCert, certIssuer, (word32)certIssuerSz, 0);
AssertIntEQ(ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL), 0);
AssertNotNull(ca = wolfSSL_d2i_X509(NULL, &certIssuer, (int)certIssuerSz));
AssertNotNull(caSubject = wolfSSL_X509_NAME_oneline(
X509_get_subject_name(ca), 0, 0));
AssertIntEQ(0, XSTRNCMP(caSubject, dCert.subject, XSTRLEN(caSubject)));
free(caSubject);
#ifdef WOLFSSL_MULTI_ATTRIB
/* test adding multiple OU's to the signer */
AssertNotNull(name = X509_get_subject_name(ca));
AssertIntEQ(X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8,
(byte*)"OU1", 3, -1, 0), SSL_SUCCESS);
AssertIntEQ(X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8,
(byte*)"OU2", 3, -1, 0), SSL_SUCCESS);
AssertIntGT(X509_sign(ca, priv, EVP_sha256()), 0);
#endif
AssertNotNull(name = X509_get_subject_name(ca));
AssertIntEQ(X509_set_issuer_name(x509, name), SSL_SUCCESS);
AssertIntGT(X509_sign(x509, priv, EVP_sha256()), 0);
AssertNotNull(caSubject = wolfSSL_X509_NAME_oneline(
X509_get_issuer_name(x509), 0, 0));
free(caSubject);
FreeDecodedCert(&dCert);
/* Test invalid parameters */
AssertIntEQ(X509_sign(NULL, priv, EVP_sha256()), 0);
@ -27844,10 +27880,11 @@ static void test_wolfSSL_X509_sign(void)
AssertIntEQ(X509_get_ext_count(x509), SSL_FAILURE);
#endif
X509_NAME_free(name);
EVP_PKEY_free(priv);
EVP_PKEY_free(pub);
X509_free(x509);
X509_free(ca);
printf(resultFmt, passed);
#endif
@ -30653,6 +30690,8 @@ static void test_wolfSSL_X509_get_serialNumber(void)
BIGNUM* bn;
X509* x509;
char *serialHex;
byte serial[3];
int serialSz;
printf(testingFmt, "wolfSSL_X509_get_serialNumber()");
@ -30663,6 +30702,40 @@ static void test_wolfSSL_X509_get_serialNumber(void)
/* check on value of ASN1 Integer */
AssertNotNull(bn = ASN1_INTEGER_to_BN(a, NULL));
/* test setting serial number and then retrieving it */
AssertNotNull(a = ASN1_INTEGER_new());
ASN1_INTEGER_set(a, 3);
AssertIntEQ(X509_set_serialNumber(x509, a), WOLFSSL_SUCCESS);
serialSz = sizeof(serial);
AssertIntEQ(wolfSSL_X509_get_serial_number(x509, serial, &serialSz),
WOLFSSL_SUCCESS);
AssertIntEQ(serialSz, 1);
AssertIntEQ(serial[0], 3);
ASN1_INTEGER_free(a);
/* test setting serial number with 0's in it */
serial[0] = 0x01;
serial[1] = 0x00;
serial[2] = 0x02;
AssertNotNull(a = wolfSSL_ASN1_INTEGER_new());
a->data[0] = ASN_INTEGER;
a->data[1] = sizeof(serial);
XMEMCPY(&a->data[2], serial, sizeof(serial));
a->length = sizeof(serial) + 2;
AssertIntEQ(X509_set_serialNumber(x509, a), WOLFSSL_SUCCESS);
XMEMSET(serial, 0, sizeof(serial));
serialSz = sizeof(serial);
AssertIntEQ(wolfSSL_X509_get_serial_number(x509, serial, &serialSz),
WOLFSSL_SUCCESS);
AssertIntEQ(serialSz, 3);
AssertIntEQ(serial[0], 0x01);
AssertIntEQ(serial[1], 0x00);
AssertIntEQ(serial[2], 0x02);
ASN1_INTEGER_free(a);
X509_free(x509); /* free's a */
AssertNotNull(serialHex = BN_bn2hex(bn));

View File

@ -5658,6 +5658,7 @@ int GetName(DecodedCert* cert, int nameType, int maxIdx)
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
&& !defined(WOLFCRYPT_ONLY)
int nid = NID_undef;
int enc;
#endif /* OPENSSL_EXTRA */
if (GetSet(cert->source, &cert->srcIdx, &dummy, maxIdx) < 0) {
@ -6048,8 +6049,20 @@ int GetName(DecodedCert* cert, int nameType, int maxIdx)
}
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
!defined(WOLFCRYPT_ONLY)
switch (b) {
case CTC_UTF8:
enc = MBSTRING_UTF8;
break;
case CTC_PRINTABLE:
enc = V_ASN1_PRINTABLESTRING;
break;
default:
WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
enc = MBSTRING_UTF8;
}
if (nid != NID_undef) {
if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, MBSTRING_UTF8,
if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
&cert->source[cert->srcIdx], strLen, -1, -1) !=
WOLFSSL_SUCCESS) {
wolfSSL_X509_NAME_free(dName);
@ -12718,6 +12731,149 @@ static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
return idx;
}
#if defined(OPENSSL_EXTRA)
/* Converts from NID_* value to wolfSSL value if needed */
static int ConvertNIDToWolfSSL(int nid)
{
switch (nid) {
case NID_commonName : return ASN_COMMON_NAME;
case NID_surname : return ASN_SUR_NAME;
case NID_countryName: return ASN_COUNTRY_NAME;
case NID_localityName: return ASN_LOCALITY_NAME;
case NID_stateOrProvinceName: return ASN_STATE_NAME;
case NID_organizationName: return ASN_ORG_NAME;
case NID_organizationalUnitName: return ASN_ORGUNIT_NAME;
case NID_emailAddress: return ASN_EMAIL_NAME;
case NID_serialNumber: return ASN_SERIAL_NUMBER;
case NID_businessCategory: return ASN_BUS_CAT;
case NID_domainComponent: return ASN_DOMAIN_COMPONENT;
default:
WOLFSSL_MSG("Attribute NID not found");
return -1;
}
}
/* Converts the x509 name structure into DER format.
*
* out pointer to either a pre setup buffer or a pointer to null for
* creating a dynamic buffer. In the case that a pre-existing buffer is
* used out will be incremented the size of the DER buffer on success.
*
* returns the size of the buffer on success, or negative value with failure
*/
int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out)
{
int totalBytes = 0, i, idx;
byte temp[MAX_SEQ_SZ];
byte *output, *local = NULL;
#ifdef WOLFSSL_SMALL_STACK
EncodedName* names = NULL;
#else
EncodedName names[MAX_NAME_ENTRIES];
#endif
if (out == NULL || name == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_SMALL_STACK
names = (EncodedName*)XMALLOC(sizeof(EncodedName) * MAX_NAME_ENTRIES, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (names == NULL)
return MEMORY_E;
#endif
XMEMSET(names, 0, sizeof(EncodedName) * MAX_NAME_ENTRIES);
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
WOLFSSL_X509_NAME_ENTRY* entry;
int ret;
entry = wolfSSL_X509_NAME_get_entry(name, i);
if (entry != NULL && entry->set == 1) {
const char* nameStr;
int type;
WOLFSSL_ASN1_STRING* data;
data = wolfSSL_X509_NAME_ENTRY_get_data(entry);
if (data == NULL) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
WOLFSSL_MSG("Error getting entry data");
return WOLFSSL_FATAL_ERROR;
}
nameStr = (const char*)wolfSSL_ASN1_STRING_data(data);
type = wolfSSL_ASN1_STRING_type(data);
switch (type) {
case MBSTRING_UTF8:
type = CTC_UTF8;
break;
case V_ASN1_PRINTABLESTRING:
type = CTC_PRINTABLE;
break;
default:
WOLFSSL_MSG("Unknown encoding type conversion UTF8 by default");
type = CTC_UTF8;
}
ret = wc_EncodeName(&names[i], nameStr, type,
ConvertNIDToWolfSSL(entry->nid));
if (ret < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
WOLFSSL_MSG("EncodeName failed");
return WOLFSSL_FATAL_ERROR;
}
totalBytes += ret;
}
}
/* header */
idx = SetSequence(totalBytes, temp);
if (totalBytes + idx > ASN_NAME_MAX) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
WOLFSSL_MSG("Total Bytes is greater than ASN_NAME_MAX");
return BUFFER_E;
}
/* check if using buffer passed in */
if (*out == NULL) {
*out = local = (unsigned char*)XMALLOC(totalBytes + idx, NULL,
DYNAMIC_TYPE_OPENSSL);
if (*out == NULL) {
return MEMORY_E;
}
}
output = *out;
idx = SetSequence(totalBytes, output);
totalBytes += idx;
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
if (names[i].used) {
XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
idx += names[i].totalLen;
}
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
/* used existing buffer passed in, so increment pointer */
if (local == NULL) {
*out += totalBytes;
}
return totalBytes;
}
#endif /* OPENSSL_EXTRA */
/* encode CertName into output, return total bytes written */
int SetName(byte* output, word32 outputSz, CertName* name)
{
@ -12977,7 +13133,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
}
/* subject name */
#ifdef WOLFSSL_CERT_EXT
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
/* Use the raw subject */
int idx;
@ -13005,13 +13161,14 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
return SUBJECT_E;
/* issuer name */
#ifdef WOLFSSL_CERT_EXT
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
if (XSTRLEN((const char*)cert->issRaw) > 0) {
/* Use the raw issuer */
int idx;
der->issuerSz = min(sizeof(der->issuer),
(word32)XSTRLEN((const char*)cert->issRaw));
/* header */
idx = SetSequence(der->issuerSz, der->issuer);
if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
@ -13601,7 +13758,29 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
/* subject name */
der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
/* Use the raw subject */
int idx;
der->subjectSz = min(sizeof(der->subject),
(word32)XSTRLEN((const char*)cert->sbjRaw));
/* header */
idx = SetSequence(der->subjectSz, der->subject);
if (der->subjectSz + idx > (int)sizeof(der->subject)) {
return SUBJECT_E;
}
XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
der->subjectSz);
der->subjectSz += idx;
}
else
#endif
{
der->subjectSz = SetName(der->subject, sizeof(der->subject),
&cert->subject);
}
if (der->subjectSz <= 0)
return SUBJECT_E;

View File

@ -6645,13 +6645,14 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_ex(void* heap)
#else
ret = wc_InitRng(&pkey->rng);
#endif
pkey->references = 1;
wc_InitMutex(&pkey->refMutex); /* init of mutex needs to come before
* wolfSSL_EVP_PKEY_free */
if (ret != 0){
wolfSSL_EVP_PKEY_free(pkey);
WOLFSSL_MSG("memory failure");
return NULL;
}
pkey->references = 1;
wc_InitMutex(&pkey->refMutex);
}
else {
WOLFSSL_MSG("memory failure");

View File

@ -69,6 +69,7 @@
#define V_ASN1_OBJECT 6
#define V_ASN1_UTCTIME 23
#define V_ASN1_GENERALIZEDTIME 24
#define V_ASN1_PRINTABLESTRING 19
#define ASN1_STRING_FLAG_BITS_LEFT 0x008
#define ASN1_STRING_FLAG_NDEF 0x010

View File

@ -366,7 +366,6 @@ enum Misc_ASN {
MAX_CERTPOL_SZ = CTC_MAX_CERTPOL_SZ,
#endif
MAX_AIA_SZ = 2, /* Max Authority Info Access extension size*/
MAX_NAME_ENTRIES = 13, /* entries added to x509 name struct */
OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */
@ -395,6 +394,12 @@ enum Misc_ASN {
PEM_LINE_LEN = PEM_LINE_SZ + 12, /* PEM line max + fudge */
};
#ifndef WC_MAX_NAME_ENTRIES
/* entries added to x509 name struct */
#define WC_MAX_NAME_ENTRIES 13
#endif
#define MAX_NAME_ENTRIES WC_MAX_NAME_ENTRIES
enum Oid_Types {
oidHashType = 0,

View File

@ -330,6 +330,8 @@ typedef struct Cert {
#endif
char certPolicies[CTC_MAX_CERTPOL_NB][CTC_MAX_CERTPOL_SZ];
word16 certPoliciesNb; /* Number of Cert Policy */
#endif
#if defined(WOLFSSL_CERT_EXT) || defined(OPENSSL_EXTRA)
byte issRaw[sizeof(CertName)]; /* raw issuer info */
byte sbjRaw[sizeof(CertName)]; /* raw subject info */
#endif