mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
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:
388
src/ssl.c
388
src/ssl.c
@ -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;
|
||||
}
|
||||
|
||||
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 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.
|
||||
* a Cert structure.
|
||||
*
|
||||
* returns WOLFSSL_SUCCESS on success and a negative error value on failure
|
||||
* returns length of DER on success and a negative error value on failure
|
||||
*/
|
||||
static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
|
||||
static int CopyX509NameToCert(WOLFSSL_X509_NAME* n, byte* out)
|
||||
{
|
||||
int idx = 0;
|
||||
#ifdef WOLFSSL_MULTI_ATTRIB
|
||||
int i, j = 0;
|
||||
#endif
|
||||
int count = 0;
|
||||
const char* current;
|
||||
byte transferred[MAX_NAME_ENTRIES] = {0};
|
||||
unsigned char* der = NULL;
|
||||
int length = BAD_FUNC_ARG, ret = BAD_FUNC_ARG;
|
||||
word32 idx = 0;
|
||||
|
||||
if (n == NULL || cName == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
ret = wolfSSL_i2d_X509_NAME(n, &der);
|
||||
if (ret > (int)sizeof(CertName) || ret < 0) {
|
||||
WOLFSSL_MSG("Name conversion error");
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
|
||||
/* 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++;
|
||||
if (ret > 0) {
|
||||
/* strip off sequence, this gets added on certificate creation */
|
||||
ret = GetSequence(der, &idx, &length, ret);
|
||||
}
|
||||
|
||||
idx++;
|
||||
current = GetOneCertName(cName, idx);
|
||||
if (ret > 0) {
|
||||
XMEMCPY(out, der + idx, length);
|
||||
}
|
||||
|
||||
#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;
|
||||
if (der != NULL)
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
|
||||
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;
|
||||
return length;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* WOLFSSL_MULTI_ATTRIB */
|
||||
|
||||
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 {
|
||||
/* 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,10 +37574,15 @@ static int CopyX509NameToCertName(WOLFSSL_X509_NAME* n, CertName* cName)
|
||||
if (x509->pubKeyOID == ECDSAk)
|
||||
wc_ecc_free(&ecc);
|
||||
#endif
|
||||
*derSz = ret;
|
||||
|
||||
if (ret > 0) {
|
||||
*derSz = ret;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
|
||||
@ -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;
|
||||
}
|
||||
|
77
tests/api.c
77
tests/api.c
@ -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 */
|
||||
@ -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));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user