Extension manipulation

This commit is contained in:
Juliusz Sosinowicz
2020-09-14 17:05:25 +02:00
parent 65c6a71bde
commit 78a20ec3ae
7 changed files with 163 additions and 76 deletions

View File

@ -4250,7 +4250,7 @@ AC_ARG_ENABLE([libest],
if test "$ENABLED_LIBEST" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST"
AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DHAVE_LIBEST -DWOLFSSL_ALT_NAMES"
# Requires opensslextra and opensslall
if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno"

View File

@ -9568,6 +9568,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
x509->subjectCN[0] = '\0';
#ifdef WOLFSSL_CERT_REQ
x509->isCSR = dCert->isCSR;
/* CSR attributes */
if (dCert->cPwd) {
if (dCert->cPwdLen < CTC_NAME_SIZE) {

207
src/ssl.c
View File

@ -8065,7 +8065,8 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
}
InitDecodedCert(&cert, rawCert, (word32)outSz, 0);
if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
if (ParseCert(&cert, passedCert->isCSR ? CERTREQ_TYPE : CA_TYPE,
NO_VERIFY, NULL) < 0) {
WOLFSSL_MSG("\tCertificate parsing failed");
return WOLFSSL_FAILURE;
}
@ -8079,16 +8080,18 @@ int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert)
return WOLFSSL_FAILURE;
}
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
FreeDecodedCert(&cert);
return WOLFSSL_FAILURE;
}
if (!passedCert->isCSR) {
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
FreeDecodedCert(&cert);
return WOLFSSL_FAILURE;
}
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
FreeDecodedCert(&cert);
return WOLFSSL_FAILURE;
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
FreeDecodedCert(&cert);
return WOLFSSL_FAILURE;
}
}
if (GetSequence(input, &idx, &length, sz) < 0) {
@ -8295,6 +8298,17 @@ const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x)
return x509->ext_sk_full;
}
/**
* Caller is responsible for freeing the returned stack.
*/
const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x)
{
const WOLFSSL_STACK *ret = wolfSSL_X509_get0_extensions(x);
if (x)
((WOLFSSL_X509*)x)->ext_sk_full = NULL;
return ret;
}
/* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509.
*
* x509 : The X509 structure to look for the extension.
@ -8389,7 +8403,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE,
NO_VERIFY, NULL) < 0) {
WOLFSSL_MSG("\tCertificate parsing failed");
wolfSSL_X509_EXTENSION_free(ext);
return NULL;
@ -8405,18 +8420,20 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
return NULL;
}
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
}
if (!x509->isCSR) {
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
}
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(&cert);
return NULL;
}
}
if (GetSequence(input, &idx, &length, sz) < 0) {
@ -9299,7 +9316,8 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
InitDecodedCert( &cert, rawCert, (word32)outSz, 0);
if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) {
if (ParseCert(&cert, x509->isCSR ? CERTREQ_TYPE : CA_TYPE,
NO_VERIFY, NULL) < 0) {
WOLFSSL_MSG("\tCertificate parsing failed");
return WOLFSSL_FATAL_ERROR;
}
@ -9313,16 +9331,18 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos)
return WOLFSSL_FATAL_ERROR;
}
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
FreeDecodedCert(&cert);
return WOLFSSL_FATAL_ERROR;
}
if (!x509->isCSR) {
if (input[idx++] != ASN_EXTENSIONS) {
WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
FreeDecodedCert(&cert);
return WOLFSSL_FATAL_ERROR;
}
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
FreeDecodedCert(&cert);
return WOLFSSL_FATAL_ERROR;
if (GetLength(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: invalid length");
FreeDecodedCert(&cert);
return WOLFSSL_FATAL_ERROR;
}
}
if (GetSequence(input, &idx, &length, sz) < 0) {
@ -9892,16 +9912,59 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
}
#ifndef NO_WOLFSSL_STUB
int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int loc)
{
WOLFSSL_STUB("wolfSSL_X509_add_ext");
(void)x509;
(void)ext;
(void)loc;
return WOLFSSL_FAILURE;
WOLFSSL_ENTER("wolfSSL_X509_add_ext");
if (!x509 || !ext || !ext->obj || loc >= 0) {
WOLFSSL_MSG("Bad parameter");
return WOLFSSL_FAILURE;
}
switch (ext->obj->type) {
case NID_subject_alt_name:
{
WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
while (gns) {
WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
if (!gn || !gn->d.ia5 ||
wolfSSL_X509_add_altname_ex(x509, gn->d.ia5->data,
gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Subject alternative name missing extension");
return WOLFSSL_FAILURE;
}
gns = gns->next;
}
x509->subjAltNameSet = 1;
x509->subjAltNameCrit = ext->crit;
break;
}
case NID_key_usage:
if (ext && ext->value.data &&
ext->value.length == sizeof(word16)) {
x509->keyUsage = *(word16*)ext->value.data;
x509->keyUsageCrit = ext->crit;
x509->keyUsageSet = 1;
}
break;
case NID_basic_constraints:
if (ext->obj) {
x509->isCa = ext->obj->ca;
x509->basicConstCrit = ext->crit;
if (ext->obj->pathlen)
x509->pathLength = ext->obj->pathlen->length;
x509->basicConstSet = 1;
}
break;
default:
WOLFSSL_MSG("Unsupported extension to add");
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#ifndef NO_WOLFSSL_STUB
WOLFSSL_X509_EXTENSION *wolfSSL_X509_delete_ext(WOLFSSL_X509 *x509, int loc)
{
WOLFSSL_STUB("wolfSSL_X509_delete_ext");
@ -39366,6 +39429,10 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
cert->challengePwPrintableString = req->challengePw[0] != 0;
#endif
#ifdef WOLFSSL_ALT_NAMES
cert->altNamesSz = FlattenAltNames(cert->altNames,
sizeof(cert->altNames), req->altNames);
#endif /* WOLFSSL_ALT_NAMES */
}
return ret;
@ -51586,6 +51653,31 @@ int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req,
return WOLFSSL_FAILURE;
}
static int wolfSSL_regen_X509_REQ_der_buffer(WOLFSSL_X509* x509)
{
byte der[4096];
int derSz = sizeof(der);
if (wolfSSL_X509_make_der(x509, 1, der, &derSz, 0) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Unable to make DER for X509 REQ");
return WOLFSSL_FAILURE;
}
FreeDer(&x509->derCert);
/* store cert for potential retrieval */
if (AllocDer(&x509->derCert, derSz, CERT_TYPE, x509->heap) == 0) {
XMEMCPY(x509->derCert->buffer, der, derSz);
}
else {
WOLFSSL_MSG("Failed to allocate DER buffer for X509");
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* ext_sk)
{
@ -51597,48 +51689,15 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req,
while (ext_sk) {
WOLFSSL_X509_EXTENSION* ext = ext_sk->data.ext;
switch (ext->obj->type) {
case NID_subject_alt_name:
{
WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
while (gns) {
WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
if (!gn || !gn->d.ia5 ||
wolfSSL_X509_add_altname_ex(req, gn->d.ia5->data,
gn->d.ia5->length, gn->type) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Subject alternative name missing extension");
return WOLFSSL_FAILURE;
}
gns = gns->next;
}
req->subjAltNameSet = 1;
req->subjAltNameCrit = ext->crit;
break;
}
case NID_key_usage:
if (ext && ext->value.data &&
ext->value.length == sizeof(word16)) {
req->keyUsage = *(word16*)ext->value.data;
req->keyUsageCrit = ext->crit;
}
break;
case NID_basic_constraints:
if (ext->obj) {
req->isCa = ext->obj->ca;
req->basicConstCrit = ext->crit;
if (ext->obj->pathlen)
req->pathLength = ext->obj->pathlen->length;
}
break;
default:
WOLFSSL_MSG("Unsupported extension to add");
if (wolfSSL_X509_add_ext(req, ext, -1) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_X509_add_ext error");
return WOLFSSL_FAILURE;
}
ext_sk = ext_sk->next;
}
return WOLFSSL_SUCCESS;
return wolfSSL_regen_X509_REQ_der_buffer(req);
}
#ifndef NO_WOLFSSL_STUB
int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req,

View File

@ -14259,6 +14259,20 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
else
der->caSz = 0;
#ifdef WOLFSSL_ALT_NAMES
/* Alternative Name */
if (cert->altNamesSz) {
der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
cert->altNames, cert->altNamesSz);
if (der->altNamesSz <= 0)
return ALT_NAME_E;
der->extensionsSz += der->altNamesSz;
}
else
der->altNamesSz = 0;
#endif
#ifdef WOLFSSL_CERT_EXT
/* SKID */
if (cert->skidSz) {
@ -14320,6 +14334,17 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
return EXTENSIONS_E;
}
#ifdef WOLFSSL_ALT_NAMES
/* put Alternative Names */
if (der->altNamesSz) {
ret = SetExtensions(der->extensions, sizeof(der->extensions),
&der->extensionsSz,
der->altNames, der->altNamesSz);
if (ret <= 0)
return EXTENSIONS_E;
}
#endif
#ifdef WOLFSSL_CERT_EXT
/* put SKID */
if (der->skidSz) {

View File

@ -3760,6 +3760,7 @@ struct WOLFSSL_X509 {
byte authKeyIdSet:1;
byte authKeyIdCrit:1;
byte issuerSet:1;
byte isCSR:1;
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
byte serial[EXTERNAL_SERIAL_SIZE];
char subjectCN[ASN_NAME_MAX]; /* common name short cut */

View File

@ -406,7 +406,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define X509V3_EXT_i2d wolfSSL_X509V3_EXT_i2d
#define X509_get0_extensions wolfSSL_X509_get0_extensions
#define X509_get_extensions wolfSSL_X509_get0_extensions
#define X509_REQ_get_extensions wolfSSL_X509_get0_extensions
#define X509_REQ_get_extensions wolfSSL_X509_REQ_get_extensions
#define X509_get_ext wolfSSL_X509_get_ext
#define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID
#define X509_get_issuer_name wolfSSL_X509_get_issuer_name

View File

@ -3429,6 +3429,7 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b);
WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_get0_extensions(const WOLFSSL_X509 *x);
WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X509 *x);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc);
WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
const WOLFSSL_ASN1_OBJECT *obj, int lastpos);