Merge pull request #6277 from anhu/upnsid

Support UPN and SID.
pull/6306/head
JacobBarthelmeh 2023-04-17 17:03:55 -06:00 committed by GitHub
commit 42b73ee326
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 538 additions and 54 deletions

View File

@ -4238,6 +4238,10 @@ void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap)
/* Free wolfSSL X509 type */
void FreeX509(WOLFSSL_X509* x509)
{
#if defined(WOLFSSL_CERT_REQ) && defined(OPENSSL_ALL) \
&& defined( WOLFSSL_CUSTOM_OID)
int idx;
#endif /* WOLFSSL_CERT_REQ && OPENSSL_ALL && WOLFSSL_CUSTOM_OID */
if (x509 == NULL)
return;
@ -4318,7 +4322,15 @@ void FreeX509(WOLFSSL_X509* x509)
if (x509->reqAttributes) {
wolfSSL_sk_pop_free(x509->reqAttributes, NULL);
}
#endif /* WOLFSSL_CERT_REQ */
#ifdef WOLFSSL_CUSTOM_OID
for (idx = 0; idx < x509->customExtCount; idx++) {
XFREE(x509->custom_exts[idx].oid, x509->heap,
DYNAMIC_TYPE_X509_EXT);
XFREE(x509->custom_exts[idx].val, x509->heap,
DYNAMIC_TYPE_X509_EXT);
}
#endif /* WOLFSSL_CUSTOM_OID */
#endif /* WOLFSSL_CERT_REQ && OPENSSL_ALL */
if (x509->altNames) {
FreeAltNames(x509->altNames, x509->heap);
x509->altNames = NULL;

View File

@ -282,6 +282,55 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION* src)
return ret;
}
WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
WOLFSSL_ASN1_STRING *data)
{
int err = 0;
WOLFSSL_X509_EXTENSION *ret = ex;
WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_create_by_OBJ");
if ((obj == NULL) || (data == NULL)) {
return NULL;
}
if (ret == NULL) {
ret = wolfSSL_X509_EXTENSION_new();
if (ret == NULL) {
err = 1;
}
} else {
/* Prevent potential memory leaks and dangling pointers. */
wolfSSL_ASN1_OBJECT_free(ret->obj);
ret->obj = NULL;
wolfSSL_ASN1_STRING_free(&ret->value);
}
ret->crit = crit;
if (err == 0) {
ret->obj = wolfSSL_ASN1_OBJECT_dup(obj);
if (ret->obj == NULL) {
err = 1;
}
}
if (err == 0) {
if (wolfSSL_ASN1_STRING_copy(&ret->value, data) != WOLFSSL_SUCCESS) {
err = 1;
}
}
if (err == 1) {
if (ret != ex) {
wolfSSL_X509_EXTENSION_free(ret);
}
ret = NULL;
}
return ret;
}
/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */
WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
{
@ -295,7 +344,9 @@ WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void)
return sk;
}
/* return 1 on success 0 on fail */
/* This function does NOT return 1 on success. It returns 0 on fail, and the
* number of items in the stack upon success. This is for compatibility with
* OpenSSL. */
int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext)
{
WOLFSSL_STACK* node;
@ -310,7 +361,7 @@ int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext
if (sk->data.ext == NULL) {
sk->data.ext = ext;
sk->num += 1;
return WOLFSSL_SUCCESS;
return (int)sk->num;
}
/* stack already has value(s) create a new node and add more */
@ -330,7 +381,7 @@ int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext
sk->data.ext = ext;
sk->num += 1;
return WOLFSSL_SUCCESS;
return (int)sk->num;
}
/* Free the structure for X509_EXTENSION stack
@ -1133,7 +1184,34 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo
WOLFSSL_GENERAL_NAMES* gns = ext->ext_sk;
while (gns) {
WOLFSSL_GENERAL_NAME* gn = gns->data.gn;
if (!gn || !gn->d.ia5 ||
if ((gn != NULL) && (gn->type == ASN_OTHER_TYPE)) {
char *buf = NULL;
int ret = 0;
word32 len = 0;
len = SetOthername(gn->d.otherName, NULL);
if (len == WOLFSSL_FAILURE) {
return WOLFSSL_FAILURE;
}
buf = (char*)XMALLOC(len, x509->heap, DYNAMIC_TYPE_X509_EXT);
if (buf == NULL) {
WOLFSSL_MSG("Couldn't allocate memory for othername");
return WOLFSSL_FAILURE;
}
/* SetOthername() cannot fail; already passed above. */
SetOthername(gn->d.otherName, (byte*)buf);
ret = wolfSSL_X509_add_altname_ex(x509, buf, len,
ASN_OTHER_TYPE);
XFREE(buf, x509->heap, DYNAMIC_TYPE_X509_EXT);
if (ret == WOLFSSL_FAILURE) {
WOLFSSL_MSG("wolfSSL_X509_add_altname_ex() failed");
return WOLFSSL_FAILURE;
}
}
else 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");
@ -1163,8 +1241,54 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext, int lo
}
break;
default:
#ifdef WOLFSSL_CUSTOM_OID
if ((ext->obj == NULL) || (ext->value.length == 0)) {
WOLFSSL_MSG("Extension has insufficient information.");
return WOLFSSL_FAILURE;
}
if ((x509->customExtCount < 0) ||
(x509->customExtCount >= NUM_CUSTOM_EXT)) {
WOLFSSL_MSG("Bad value for customExtCount.");
return WOLFSSL_FAILURE;
}
/* This is a viable custom extension. */
char *oid = XMALLOC(MAX_OID_STRING_SZ, x509->heap,
DYNAMIC_TYPE_X509_EXT);
byte *val = XMALLOC(ext->value.length, x509->heap,
DYNAMIC_TYPE_X509_EXT);
int err = 0;
if ((oid == NULL) || (val == NULL)) {
WOLFSSL_MSG("Memory allocation failure.\n");
err = 1;
}
if (err == 0) {
XMEMCPY(val, ext->value.data, ext->value.length);
if (wolfSSL_OBJ_obj2txt(oid, MAX_OID_STRING_SZ, ext->obj, 1) < 0) {
err = 1;
}
}
if (err == 1) {
XFREE(val, x509->heap, DYNAMIC_TYPE_X509_EXT);
XFREE(oid, x509->heap, DYNAMIC_TYPE_X509_EXT);
return WOLFSSL_FAILURE;
}
/* x509->custom_exts now owns the buffers and they must be managed. */
x509->custom_exts[x509->customExtCount].oid = oid;
x509->custom_exts[x509->customExtCount].crit = ext->crit;
x509->custom_exts[x509->customExtCount].val = val;
x509->custom_exts[x509->customExtCount].valSz = ext->value.length;
x509->customExtCount++;
#else
WOLFSSL_MSG("Unsupported extension to add");
return WOLFSSL_FAILURE;
#endif /* WOLFSSL_CUSTOM_OID */
break;
}
return WOLFSSL_SUCCESS;
@ -2697,6 +2821,12 @@ WOLFSSL_X509_EXTENSION *wolfSSL_X509V3_EXT_i2d(int nid, int crit,
WOLFSSL_MSG("wolfSSL_sk_dup failed");
goto err_cleanup;
}
if (!(ext->obj = wolfSSL_OBJ_nid2obj(nid))) {
WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new failed");
goto err_cleanup;
}
break;
}
case NID_basic_constraints:
@ -3343,6 +3473,7 @@ WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
return d2i_X509orX509REQ(x509, in, len, 1);
}
#endif
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
OPENSSL_EXTRA_X509_SMALL */
@ -4005,6 +4136,7 @@ WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void)
wolfSSL_GENERAL_NAME_free(gn);
return NULL;
}
gn->type = GEN_IA5;
return gn;
}
@ -4024,6 +4156,8 @@ WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
return NULL;
}
wolfSSL_ASN1_STRING_free(dupl->d.ia5);
dupl->d.ia5 = NULL;
switch (gn->type) {
/* WOLFSSL_ASN1_STRING types */
case GEN_DNS:
@ -4052,6 +4186,37 @@ WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn)
}
break;
case GEN_OTHERNAME:
if (gn->d.otherName->value->type != V_ASN1_UTF8STRING) {
WOLFSSL_MSG("Unsupported othername value type");
goto error;
}
dupl->d.otherName = (WOLFSSL_ASN1_OTHERNAME*)XMALLOC(
sizeof(WOLFSSL_ASN1_OTHERNAME), NULL, DYNAMIC_TYPE_ASN1);
if (dupl->d.otherName == NULL) {
WOLFSSL_MSG("XMALLOC error");
goto error;
}
dupl->d.otherName->type_id = wolfSSL_ASN1_OBJECT_dup(
gn->d.otherName->type_id);
dupl->d.otherName->value = (WOLFSSL_ASN1_TYPE*)XMALLOC(
sizeof(WOLFSSL_ASN1_TYPE), NULL, DYNAMIC_TYPE_ASN1);
if (dupl->d.otherName->value != NULL) {
dupl->d.otherName->value->type = gn->d.otherName->value->type;
dupl->d.otherName->value->value.utf8string =
wolfSSL_ASN1_STRING_dup(
gn->d.otherName->value->value.utf8string);
}
if ((dupl->d.otherName->type_id == NULL) ||
(dupl->d.otherName->value == NULL) ||
(dupl->d.otherName->value->value.utf8string == NULL)) {
wolfSSL_ASN1_OBJECT_free(dupl->d.otherName->type_id);
wolfSSL_ASN1_TYPE_free(dupl->d.otherName->value);
XFREE(dupl->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
dupl->d.otherName = NULL;
WOLFSSL_MSG("error duping othername");
goto error;
}
break;
case GEN_X400:
case GEN_DIRNAME:
case GEN_EDIPARTY:
@ -4070,6 +4235,33 @@ error:
return NULL;
}
/* Set an Othername in a general name.
*
* @param [out] gen Pointer to the GENERAL_NAME where the othername is set.
* @param [in] oid Object ID (ie UPN).
* @param [in] name The actual name.
* @return WOLFSSL_FAILURE on invalid parameter or memory error,
* WOLFSSL_SUCCESS otherwise.
*/
int wolfSSL_GENERAL_NAME_set0_othername(GENERAL_NAME* gen, ASN1_OBJECT* oid,
ASN1_TYPE* value) {
WOLFSSL_ASN1_OBJECT *x = NULL;
if ((gen == NULL) || (oid == NULL) || (value == NULL)) {
return WOLFSSL_FAILURE;
}
x = wolfSSL_ASN1_OBJECT_dup(oid);
if (x == NULL) {
WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup() failed");
return WOLFSSL_FAILURE;
}
gen->type = GEN_OTHERNAME;
gen->d.otherName->type_id = x;
gen->d.otherName->value = value;
return WOLFSSL_SUCCESS;
}
/* return 1 on success 0 on fail */
int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
@ -4153,6 +4345,19 @@ int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk)
return (int)sk->num;
}
/* Allocates an empty GENERAL NAME stack */
WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc) {
WOLFSSL_STACK* sk = NULL;
(void)cmpFunc;
WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_new");
sk = wolfSSL_sk_new_null();
if (sk != NULL) {
sk->type = STACK_TYPE_GEN_NAME;
}
return sk;
}
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
@ -4363,34 +4568,52 @@ WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value(
static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name)
{
if (name != NULL) {
if (name->d.dNSName != NULL) {
wolfSSL_ASN1_STRING_free(name->d.dNSName);
name->d.dNSName = NULL;
}
if (name->d.dirn != NULL) {
wolfSSL_X509_NAME_free(name->d.dirn);
name->d.dirn = NULL;
}
if (name->d.uniformResourceIdentifier != NULL) {
wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
name->d.uniformResourceIdentifier = NULL;
}
if (name->d.iPAddress != NULL) {
wolfSSL_ASN1_STRING_free(name->d.iPAddress);
name->d.iPAddress = NULL;
}
if (name->d.registeredID != NULL) {
wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
name->d.registeredID = NULL;
}
if (name->d.ia5 != NULL) {
switch (name->type) {
case GEN_IA5:
wolfSSL_ASN1_STRING_free(name->d.ia5);
name->d.ia5 = NULL;
break;
case GEN_EMAIL:
wolfSSL_ASN1_STRING_free(name->d.rfc822Name);
name->d.rfc822Name = NULL;
break;
case GEN_DNS:
wolfSSL_ASN1_STRING_free(name->d.dNSName);
name->d.dNSName = NULL;
break;
case GEN_DIRNAME:
wolfSSL_X509_NAME_free(name->d.dirn);
name->d.dirn = NULL;
break;
case GEN_URI:
wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier);
name->d.uniformResourceIdentifier = NULL;
break;
case GEN_IPADD:
wolfSSL_ASN1_STRING_free(name->d.iPAddress);
name->d.iPAddress = NULL;
break;
case GEN_RID:
wolfSSL_ASN1_OBJECT_free(name->d.registeredID);
name->d.registeredID = NULL;
break;
case GEN_OTHERNAME:
wolfSSL_ASN1_OBJECT_free(name->d.otherName->type_id);
wolfSSL_ASN1_TYPE_free(name->d.otherName->value);
XFREE(name->d.otherName, NULL, DYNAMIC_TYPE_ASN1);
name->d.otherName = NULL;
break;
case GEN_X400:
/* Unsupported: fall through */
case GEN_EDIPARTY:
/* Unsupported: fall through */
default:
WOLFSSL_MSG("wolfSSL_GENERAL_NAME_type_free: possible leak");
break;
}
}
}
/* sets the general name type and free's the existing one
* can fail with a memory error if malloc fails or bad arg error
* otherwise return WOLFSSL_SUCCESS */
@ -4409,6 +4632,7 @@ int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ)
ret = MEMORY_E;
break;
default:
name->type = GEN_IA5;
name->d.ia5 = wolfSSL_ASN1_STRING_new();
if (name->d.ia5 == NULL)
ret = MEMORY_E;
@ -7211,6 +7435,11 @@ static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
}
#endif
#ifdef WOLFSSL_CERT_REQ
else if (type == CERTREQ_TYPE) {
newx509 = (void *)wolfSSL_X509_REQ_d2i(NULL, fileBuffer, (int)sz);
}
#endif
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
else if (type == PKCS12_TYPE) {
if ((newx509 = wc_PKCS12_new()) == NULL) {
@ -7249,11 +7478,20 @@ _exit:
return newx509;
}
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req)
{
return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)req,
CERTREQ_TYPE);
}
#endif /* WOLFSSL_CERT_REQ */
WOLFSSL_X509 *wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509 **x509)
{
WOLFSSL_ENTER("wolfSSL_d2i_X509_fp");
return (WOLFSSL_X509 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)x509, CERT_TYPE);
}
/* load certificate or CRL file, and add it to the STORE */
/* @param ctx a pointer to X509_LOOKUP structure */
/* @param file file name to load */
@ -9228,11 +9466,33 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
}
}
}
#ifdef WOLFSSL_CUSTOM_OID
if (ret == WOLFSSL_SUCCESS) {
if ((req->customExtCount < 0) ||
(req->customExtCount >= NUM_CUSTOM_EXT)) {
WOLFSSL_MSG("Bad value for customExtCount.");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS) {
for (idx = 0; idx < req->customExtCount; idx++) {
/* Note that ownership is NOT transfered.
* req->custom_exts buffers still need to be cleaned
* up. */
cert->customCertExt[idx] = req->custom_exts[idx];
}
cert->customCertExtCount = req->customExtCount;
}
}
#endif /* WOLFSSL_CUSTOM_OID */
#endif /* OPENSSL_ALL */
#ifdef WOLFSSL_ALT_NAMES
cert->altNamesSz = FlattenAltNames(cert->altNames,
sizeof(cert->altNames), req->altNames);
if (ret == WOLFSSL_SUCCESS) {
cert->altNamesSz = FlattenAltNames(cert->altNames,
sizeof(cert->altNames), req->altNames);
}
#endif /* WOLFSSL_ALT_NAMES */
}

View File

@ -43264,6 +43264,142 @@ static int test_wolfSSL_X509_NAME_ENTRY(void)
return res;
}
/* Note the lack of wolfSSL_ prefix...this is a compatability layer test. */
static int test_GENERAL_NAME_set0_othername(void) {
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM)
const char * cert_fname = "./certs/server-cert.der";
const char * key_fname = "./certs/server-key.der";
X509* x509 = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAMES* gns = NULL;
ASN1_OBJECT* upn_oid = NULL;
ASN1_UTF8STRING *utf8str = NULL;
ASN1_TYPE *value = NULL;
X509_EXTENSION * ext = NULL;
byte* pt = NULL;
byte der[4096];
int derSz = 0;
EVP_PKEY* priv = NULL;
FILE* f = NULL;
AssertNotNull(f = fopen(cert_fname, "rb"));
AssertNotNull(x509 = d2i_X509_fp(f, NULL));
fclose(f);
AssertNotNull(gn = GENERAL_NAME_new());
AssertNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
AssertNotNull(utf8str = ASN1_UTF8STRING_new());
AssertIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
AssertNotNull(value = ASN1_TYPE_new());
ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
AssertIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
AssertNotNull(gns = sk_GENERAL_NAME_new(NULL));
AssertIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
AssertNotNull(ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
AssertIntEQ(X509_add_ext(x509, ext, -1), 1);
AssertNotNull(f = fopen(key_fname, "rb"));
AssertIntGT(derSz = (int)fread(der, 1, sizeof(der), f), 0);
fclose(f);
pt = der;
AssertNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
(const unsigned char**)&pt, derSz));
AssertIntGT(X509_sign(x509, priv, EVP_sha256()), 0);
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
ASN1_OBJECT_free(upn_oid);
X509_EXTENSION_free(ext);
X509_free(x509);
EVP_PKEY_free(priv);
res = TEST_RES_CHECK(1);
#endif
return res;
}
/* Note the lack of wolfSSL_ prefix...this is a compatability layer test. */
static int test_othername_and_SID_ext(void) {
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM)
const char* csr_fname = "./certs/csr.signed.der";
const char* key_fname = "./certs/server-key.der";
byte der[4096];
int derSz = 0;
X509_REQ* x509 = NULL;
STACK_OF(X509_EXTENSION) *exts = NULL;
X509_EXTENSION * san_ext = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAMES* gns = NULL;
ASN1_OBJECT* upn_oid = NULL;
ASN1_UTF8STRING *utf8str = NULL;
ASN1_TYPE *value = NULL;
/* SID extension. SID data format explained here:
* https://blog.qdsecurity.se/2022/05/27/manually-injecting-a-sid-in-a-certificate/
*/
uint8_t SidExtension[] = {
48, 64, 160, 62, 6, 10, 43, 6, 1, 4, 1, 130, 55, 25, 2, 1, 160,
48, 4, 46, 83, 45, 49, 45, 53, 45, 50, 49, 45, 50, 56, 52, 51, 57,
48, 55, 52, 49, 56, 45, 51, 57, 50, 54, 50, 55, 55, 52, 50, 49, 45,
51, 56, 49, 53, 57, 57, 51, 57, 55, 50, 45, 52, 54, 48, 49};
X509_EXTENSION *sid_ext = NULL;
ASN1_OBJECT* sid_oid = NULL;
ASN1_OCTET_STRING *sid_data = NULL;
EVP_PKEY* priv = NULL;
FILE* f = NULL;
byte* pt = NULL;
AssertNotNull(f = fopen(csr_fname, "rb"));
AssertNotNull(x509 = d2i_X509_REQ_fp(f, NULL));
fclose(f);
AssertIntEQ(X509_REQ_set_version(x509, 2), 1);
AssertNotNull(gn = GENERAL_NAME_new());
AssertNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
AssertNotNull(utf8str = ASN1_UTF8STRING_new());
AssertIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
AssertNotNull(value = ASN1_TYPE_new());
ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
AssertIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
AssertNotNull(gns = sk_GENERAL_NAME_new(NULL));
AssertIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
AssertNotNull(san_ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
AssertNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1));
AssertNotNull(sid_data = ASN1_OCTET_STRING_new());
ASN1_OCTET_STRING_set(sid_data, SidExtension, sizeof(SidExtension));
AssertNotNull(sid_ext = X509_EXTENSION_create_by_OBJ(NULL, sid_oid, 0,
sid_data));
AssertNotNull(exts = sk_X509_EXTENSION_new_null());
AssertIntEQ(sk_X509_EXTENSION_push(exts, san_ext), 1);
AssertIntEQ(sk_X509_EXTENSION_push(exts, sid_ext), 2);
AssertIntEQ(X509_REQ_add_extensions(x509, exts), 1);
AssertNotNull(f = fopen(key_fname, "rb"));
AssertIntGT(derSz = (int)fread(der, 1, sizeof(der), f), 0);
fclose(f);
pt = der;
AssertNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
(const unsigned char**)&pt, derSz));
AssertIntGT(X509_REQ_sign(x509, priv, EVP_sha256()), 0);
pt = der;
AssertIntGT(derSz = i2d_X509_REQ(x509, &pt), 0);
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
ASN1_OBJECT_free(upn_oid);
ASN1_OBJECT_free(sid_oid);
ASN1_OCTET_STRING_free(sid_data);
X509_REQ_free(x509);
EVP_PKEY_free(priv);
res = TEST_RES_CHECK(1);
#endif
return res;
}
static int test_wolfSSL_X509_set_name(void)
{
@ -45135,7 +45271,6 @@ static int test_wolfSSL_GENERAL_NAME_print(void)
const char* x400Str = "X400Name:<unsupported>";
const char* ediStr = "EdiPartyName:<unsupported>";
/* BIO to output */
AssertNotNull(out = BIO_new(BIO_s_mem()));
@ -45261,6 +45396,8 @@ static int test_wolfSSL_GENERAL_NAME_print(void)
AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
AssertIntEQ(XSTRNCMP((const char*)outbuf, x400Str, XSTRLEN(x400Str)), 0);
/* Restore to GEN_IA5 (default) to avoid memory leak. */
gn->type = GEN_IA5;
GENERAL_NAME_free(gn);
/* test for GEN_EDIPARTY */
@ -45273,6 +45410,8 @@ static int test_wolfSSL_GENERAL_NAME_print(void)
AssertIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
AssertIntEQ(XSTRNCMP((const char*)outbuf, ediStr, XSTRLEN(ediStr)), 0);
/* Restore to GEN_IA5 (default) to avoid memory leak. */
gn->type = GEN_IA5;
GENERAL_NAME_free(gn);
BIO_free(out);
@ -65153,6 +65292,8 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_OBJ_txt2obj),
TEST_DECL(test_wolfSSL_PEM_write_bio_X509),
TEST_DECL(test_wolfSSL_X509_NAME_ENTRY),
TEST_DECL(test_GENERAL_NAME_set0_othername),
TEST_DECL(test_othername_and_SID_ext),
TEST_DECL(test_wolfSSL_X509_set_name),
TEST_DECL(test_wolfSSL_X509_set_notAfter),
TEST_DECL(test_wolfSSL_X509_set_notBefore),

View File

@ -14574,6 +14574,49 @@ word32 SetExplicit(byte number, word32 len, byte* output)
output);
}
#if defined(OPENSSL_EXTRA)
/* Encode an Othername into DER.
*
* @param [in] name Pointer to the WOLFSSL_ASN1_OTHERNAME to be encoded.
* @param [out] output Buffer to encode into. If NULL, don't encode.
* @return Number of bytes encoded or WOLFSSL_FAILURE if name parameter is bad.
*/
word32 SetOthername(void *name, byte *output)
{
WOLFSSL_ASN1_OTHERNAME *nm = (WOLFSSL_ASN1_OTHERNAME *)name;
char *nameStr = NULL;
int nameSz = 0;
word32 len = 0;
if ((nm == NULL) || (nm->value == NULL)) {
WOLFSSL_MSG("otherName value is NULL");
return WOLFSSL_FAILURE;
}
nameStr = nm->value->value.utf8string->data;
nameSz = nm->value->value.utf8string->length;
len = nm->type_id->objSz +
SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2, NULL) +
SetHeader(CTC_UTF8, nameSz, NULL) + nameSz;
if (output != NULL) {
/* otherName OID */
XMEMCPY(output, nm->type_id->obj, nm->type_id->objSz);
output += nm->type_id->objSz;
output += SetHeader(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC, nameSz + 2,
output);
output += SetHeader(CTC_UTF8, nameSz, output);
XMEMCPY(output, nameStr, nameSz);
output += nameSz;
}
return len;
}
#endif /* OPENSSL_EXTRA */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
@ -25949,7 +25992,7 @@ int FlattenAltNames(byte* output, word32 outputSz, const DNS_entry* names)
i = idx;
#endif
output[idx] = (byte) (ASN_CONTEXT_SPECIFIC | curName->type);
if (curName->type == ASN_DIR_TYPE) {
if (curName->type == ASN_DIR_TYPE || curName->type == ASN_OTHER_TYPE) {
output[idx] |= ASN_CONSTRUCTED;
}
idx++;

View File

@ -4802,6 +4802,10 @@ struct WOLFSSL_X509 {
byte authKeyIdSet:1;
byte authKeyIdCrit:1;
byte issuerSet:1;
#ifdef WOLFSSL_CUSTOM_OID
CertExtension custom_exts[NUM_CUSTOM_EXT];
int customExtCount;
#endif /* WOLFSSL_CUSTOM_OID */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef WOLFSSL_CERT_REQ
byte isCSR:1;

View File

@ -185,5 +185,7 @@ WOLFSSL_API int wolfSSL_ASN1_item_i2d(const void *src, byte **dest,
#define BN_to_ASN1_INTEGER wolfSSL_BN_to_ASN1_INTEGER
#define ASN1_TYPE_set wolfSSL_ASN1_TYPE_set
#define ASN1_TYPE_new wolfSSL_ASN1_TYPE_new
#define ASN1_TYPE_free wolfSSL_ASN1_TYPE_free
#endif /* WOLFSSL_ASN1_H_ */

View File

@ -110,7 +110,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING;
typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value;
typedef WOLFSSL_BUF_MEM BUF_MEM;
typedef WOLFSSL_GENERAL_NAMES GENERAL_NAMES;
typedef WOLFSSL_GENERAL_NAME GENERAL_NAME;
typedef WOLFSSL_GENERAL_NAME GENERAL_NAME;
typedef WOLFSSL_OBJ_NAME OBJ_NAME;
typedef WOLFSSL_DIST_POINT_NAME DIST_POINT_NAME;
typedef WOLFSSL_DIST_POINT DIST_POINT;
@ -392,16 +392,17 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define SSL_SESSION_get_max_early_data wolfSSL_SESSION_get_max_early_data
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
#define SSL_MODE_RELEASE_BUFFERS 0x00000010U
#define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN
#define X509_get_ext wolfSSL_X509_get_ext
#define X509_get_ext_by_OBJ wolfSSL_X509_get_ext_by_OBJ
#define X509_cmp wolfSSL_X509_cmp
#define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object
#define X509_EXTENSION_get_critical wolfSSL_X509_EXTENSION_get_critical
#define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data
#define X509_EXTENSION_new wolfSSL_X509_EXTENSION_new
#define X509_EXTENSION_free wolfSSL_X509_EXTENSION_free
#define SSL_MODE_RELEASE_BUFFERS 0x00000010U
#define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN
#define X509_get_ext wolfSSL_X509_get_ext
#define X509_get_ext_by_OBJ wolfSSL_X509_get_ext_by_OBJ
#define X509_cmp wolfSSL_X509_cmp
#define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object
#define X509_EXTENSION_get_critical wolfSSL_X509_EXTENSION_get_critical
#define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data
#define X509_EXTENSION_new wolfSSL_X509_EXTENSION_new
#define X509_EXTENSION_free wolfSSL_X509_EXTENSION_free
#define X509_EXTENSION_create_by_OBJ wolfSSL_X509_EXTENSION_create_by_OBJ
#endif
#define DSA_dup_DH wolfSSL_DSA_dup_DH
@ -415,6 +416,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define i2d_X509_REQ_bio wolfSSL_i2d_X509_REQ_bio
#define d2i_X509_bio wolfSSL_d2i_X509_bio
#define d2i_X509_REQ_bio wolfSSL_d2i_X509_REQ_bio
#define d2i_X509_REQ_fp wolfSSL_d2i_X509_REQ_fp
#define d2i_X509_fp wolfSSL_d2i_X509_fp
#define i2d_X509 wolfSSL_i2d_X509
#define d2i_X509 wolfSSL_d2i_X509
@ -878,6 +880,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define ASN1_OCTET_STRING_free wolfSSL_ASN1_STRING_free
#define ASN1_OCTET_STRING_set wolfSSL_ASN1_STRING_set
#define ASN1_UTF8STRING WOLFSSL_ASN1_STRING
#define ASN1_UTF8STRING_new wolfSSL_ASN1_STRING_new
#define ASN1_UTF8STRING_free wolfSSL_ASN1_STRING_free
#define ASN1_UTF8STRING_set wolfSSL_ASN1_STRING_set
#define ASN1_PRINTABLE_type(...) V_ASN1_PRINTABLESTRING
#define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr
@ -1345,6 +1352,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free
#define GENERAL_NAME_dup wolfSSL_GENERAL_NAME_dup
#define GENERAL_NAME_print wolfSSL_GENERAL_NAME_print
#define GENERAL_NAME_set0_othername wolfSSL_GENERAL_NAME_set0_othername
#define sk_GENERAL_NAME_push wolfSSL_sk_GENERAL_NAME_push
#define sk_GENERAL_NAME_value wolfSSL_sk_GENERAL_NAME_value
@ -1367,6 +1375,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define SSL_SESSION_set1_id_context wolfSSL_SESSION_set1_id_context
#define SSL_SESSION_print wolfSSL_SESSION_print
#define sk_GENERAL_NAME_pop_free wolfSSL_sk_GENERAL_NAME_pop_free
#define sk_GENERAL_NAME_new wolfSSL_sk_GENERAL_NAME_new
#define sk_GENERAL_NAME_free wolfSSL_sk_GENERAL_NAME_free
#define sk_ASN1_OBJECT_pop_free wolfSSL_sk_ASN1_OBJECT_pop_free
#define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free

View File

@ -109,6 +109,7 @@ struct WOLFSSL_X509_EXTENSION {
#define GEN_URI 6
#define GEN_IPADD 7
#define GEN_RID 8
#define GEN_IA5 9
#define GENERAL_NAME WOLFSSL_GENERAL_NAME

View File

@ -1557,6 +1557,11 @@ WOLFSSL_API int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name,
int typ);
WOLFSSL_API WOLFSSL_GENERAL_NAMES* wolfSSL_GENERAL_NAMES_dup(
WOLFSSL_GENERAL_NAMES* gns);
WOLFSSL_API int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen,
WOLFSSL_ASN1_OBJECT* oid,
WOLFSSL_ASN1_TYPE* value);
WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_GENERAL_NAME_new(void *cmpFunc);
WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk,
WOLFSSL_GENERAL_NAME* gn);
WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(
@ -4279,6 +4284,9 @@ WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x,
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc);
WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_create_by_OBJ(
WOLFSSL_X509_EXTENSION* ex, WOLFSSL_ASN1_OBJECT *obj, int crit,
WOLFSSL_ASN1_STRING *data);
WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(
WOLFSSL_X509_EXTENSION* src);
WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,
@ -4316,6 +4324,9 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio,
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio,
WOLFSSL_X509** x509);
#if !defined(NO_FILESYSTEM)
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_REQ_fp(XFILE fp, WOLFSSL_X509 **req);
#endif
#endif
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */

View File

@ -2166,6 +2166,9 @@ WOLFSSL_LOCAL word32 SetAlgoID(int algoOID,byte* output,int type,int curveSz);
WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
word32 outputSz, int maxSnSz);
/* name is of type WOLFSSL_ASN1_OTHERNAME; use void* to avoid including ssl.h */
WOLFSSL_LOCAL word32 SetOthername(void *name, byte *output);
#ifndef WOLFSSL_ASN_TEMPLATE
WOLFSSL_LOCAL int wc_GetSerialNumber(const byte* input, word32* inOutIdx,
byte* serial, int* serialSz, word32 maxIdx);

View File

@ -351,7 +351,6 @@ typedef struct NameAttrib {
#endif /* WOLFSSL_MULTI_ATTRIB */
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef WOLFSSL_CERT_GEN
#ifdef WOLFSSL_CUSTOM_OID
typedef struct CertOidField {
byte* oid;
@ -362,13 +361,12 @@ typedef struct CertOidField {
} CertOidField;
typedef struct CertExtension {
const char* oid;
byte crit;
const byte* val;
int valSz;
char* oid;
byte crit;
byte* val;
int valSz;
} CertExtension;
#endif
#endif /* WOLFSSL_CERT_GEN */
#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
typedef struct CertName {
@ -422,11 +420,8 @@ typedef struct CertName {
} CertName;
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL*/
#ifdef WOLFSSL_CERT_GEN
#ifndef NUM_CUSTOM_EXT
#define NUM_CUSTOM_EXT 16
#endif
/* for user to fill for certificate generation */
typedef struct Cert {
@ -434,10 +429,13 @@ typedef struct Cert {
byte serial[CTC_SERIAL_SIZE]; /* serial number */
int serialSz; /* serial size */
int sigType; /* signature algo type */
#if defined(WOLFSSL_CERT_GEN) || defined(OPENSSL_EXTRA) \
|| defined(OPENSSL_EXTRA_X509_SMALL)
CertName issuer; /* issuer info */
CertName subject; /* subject info */
#endif /* WOLFSSL_CERT_GEN || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
int daysValid; /* validity days */
int selfSigned; /* self signed flag */
CertName subject; /* subject info */
int isCA; /* is this going to be a CA */
byte pathLen; /* max depth of valid certification
* paths that include this cert */
@ -492,7 +490,7 @@ typedef struct Cert {
char challengePw[CTC_NAME_SIZE];
char unstructuredName[CTC_NAME_SIZE];
int challengePwPrintableString; /* encode as PrintableString */
#endif
#endif /* WOLFSSL_CERT_REQ */
#ifdef WOLFSSL_CUSTOM_OID
/* user oid and value to go in req extensions */
CertOidField extCustom;
@ -500,7 +498,7 @@ typedef struct Cert {
/* Extensions to go into X.509 certificates */
CertExtension customCertExt[NUM_CUSTOM_EXT];
int customCertExtCount;
#endif
#endif /* WOLFSSL_CUSTOM_OID */
void* decodedCert; /* internal DecodedCert allocated from heap */
byte* der; /* Pointer to buffer of current DecodedCert cache */
void* heap; /* heap hint */