1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "crypto/ctype.h" 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 14e1051a39Sopenharmony_ci#include <openssl/x509.h> 15e1051a39Sopenharmony_ci#include "crypto/x509.h" 16e1051a39Sopenharmony_ci#include "crypto/asn1.h" 17e1051a39Sopenharmony_ci#include "x509_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci/* 20e1051a39Sopenharmony_ci * Maximum length of X509_NAME: much larger than anything we should 21e1051a39Sopenharmony_ci * ever see in practice. 22e1051a39Sopenharmony_ci */ 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci#define X509_NAME_MAX (1024 * 1024) 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_cistatic int x509_name_ex_d2i(ASN1_VALUE **val, 27e1051a39Sopenharmony_ci const unsigned char **in, long len, 28e1051a39Sopenharmony_ci const ASN1_ITEM *it, 29e1051a39Sopenharmony_ci int tag, int aclass, char opt, ASN1_TLC *ctx); 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_cistatic int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out, 32e1051a39Sopenharmony_ci const ASN1_ITEM *it, int tag, int aclass); 33e1051a39Sopenharmony_cistatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); 34e1051a39Sopenharmony_cistatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_cistatic int x509_name_encode(X509_NAME *a); 37e1051a39Sopenharmony_cistatic int x509_name_canon(X509_NAME *a); 38e1051a39Sopenharmony_cistatic int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in); 39e1051a39Sopenharmony_cistatic int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, 40e1051a39Sopenharmony_ci unsigned char **in); 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_cistatic int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval, 43e1051a39Sopenharmony_ci int indent, 44e1051a39Sopenharmony_ci const char *fname, const ASN1_PCTX *pctx); 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ciASN1_SEQUENCE(X509_NAME_ENTRY) = { 47e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), 48e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) 49e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END(X509_NAME_ENTRY) 50e1051a39Sopenharmony_ci 51e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) 52e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci/* 55e1051a39Sopenharmony_ci * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so 56e1051a39Sopenharmony_ci * declare two template wrappers for this 57e1051a39Sopenharmony_ci */ 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ciASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = 60e1051a39Sopenharmony_ci ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) 61e1051a39Sopenharmony_cistatic_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ciASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = 64e1051a39Sopenharmony_ci ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) 65e1051a39Sopenharmony_cistatic_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci/* 68e1051a39Sopenharmony_ci * Normally that's where it would end: we'd have two nested STACK structures 69e1051a39Sopenharmony_ci * representing the ASN1. Unfortunately X509_NAME uses a completely different 70e1051a39Sopenharmony_ci * form and caches encodings so we have to process the internal form and 71e1051a39Sopenharmony_ci * convert to the external form. 72e1051a39Sopenharmony_ci */ 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_cistatic const ASN1_EXTERN_FUNCS x509_name_ff = { 75e1051a39Sopenharmony_ci NULL, 76e1051a39Sopenharmony_ci x509_name_ex_new, 77e1051a39Sopenharmony_ci x509_name_ex_free, 78e1051a39Sopenharmony_ci 0, /* Default clear behaviour is OK */ 79e1051a39Sopenharmony_ci x509_name_ex_d2i, 80e1051a39Sopenharmony_ci x509_name_ex_i2d, 81e1051a39Sopenharmony_ci x509_name_ex_print 82e1051a39Sopenharmony_ci}; 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ciIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_NAME) 87e1051a39Sopenharmony_ci 88e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_cistatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) 91e1051a39Sopenharmony_ci{ 92e1051a39Sopenharmony_ci X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret)); 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci if (ret == NULL) 95e1051a39Sopenharmony_ci goto memerr; 96e1051a39Sopenharmony_ci if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) 97e1051a39Sopenharmony_ci goto memerr; 98e1051a39Sopenharmony_ci if ((ret->bytes = BUF_MEM_new()) == NULL) 99e1051a39Sopenharmony_ci goto memerr; 100e1051a39Sopenharmony_ci ret->modified = 1; 101e1051a39Sopenharmony_ci *val = (ASN1_VALUE *)ret; 102e1051a39Sopenharmony_ci return 1; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci memerr: 105e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 106e1051a39Sopenharmony_ci if (ret) { 107e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_free(ret->entries); 108e1051a39Sopenharmony_ci OPENSSL_free(ret); 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci return 0; 111e1051a39Sopenharmony_ci} 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_cistatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 114e1051a39Sopenharmony_ci{ 115e1051a39Sopenharmony_ci X509_NAME *a; 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci if (pval == NULL || *pval == NULL) 118e1051a39Sopenharmony_ci return; 119e1051a39Sopenharmony_ci a = (X509_NAME *)*pval; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci BUF_MEM_free(a->bytes); 122e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); 123e1051a39Sopenharmony_ci OPENSSL_free(a->canon_enc); 124e1051a39Sopenharmony_ci OPENSSL_free(a); 125e1051a39Sopenharmony_ci *pval = NULL; 126e1051a39Sopenharmony_ci} 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_cistatic void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) 129e1051a39Sopenharmony_ci{ 130e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_free(ne); 131e1051a39Sopenharmony_ci} 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_cistatic void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) 134e1051a39Sopenharmony_ci{ 135e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); 136e1051a39Sopenharmony_ci} 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_cistatic int x509_name_ex_d2i(ASN1_VALUE **val, 139e1051a39Sopenharmony_ci const unsigned char **in, long len, 140e1051a39Sopenharmony_ci const ASN1_ITEM *it, int tag, int aclass, 141e1051a39Sopenharmony_ci char opt, ASN1_TLC *ctx) 142e1051a39Sopenharmony_ci{ 143e1051a39Sopenharmony_ci const unsigned char *p = *in, *q; 144e1051a39Sopenharmony_ci union { 145e1051a39Sopenharmony_ci STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 146e1051a39Sopenharmony_ci ASN1_VALUE *a; 147e1051a39Sopenharmony_ci } intname = { 148e1051a39Sopenharmony_ci NULL 149e1051a39Sopenharmony_ci }; 150e1051a39Sopenharmony_ci union { 151e1051a39Sopenharmony_ci X509_NAME *x; 152e1051a39Sopenharmony_ci ASN1_VALUE *a; 153e1051a39Sopenharmony_ci } nm = { 154e1051a39Sopenharmony_ci NULL 155e1051a39Sopenharmony_ci }; 156e1051a39Sopenharmony_ci int i, j, ret; 157e1051a39Sopenharmony_ci STACK_OF(X509_NAME_ENTRY) *entries; 158e1051a39Sopenharmony_ci X509_NAME_ENTRY *entry; 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci if (len > X509_NAME_MAX) 161e1051a39Sopenharmony_ci len = X509_NAME_MAX; 162e1051a39Sopenharmony_ci q = p; 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci /* Get internal representation of Name */ 165e1051a39Sopenharmony_ci ret = ASN1_item_ex_d2i(&intname.a, 166e1051a39Sopenharmony_ci &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), 167e1051a39Sopenharmony_ci tag, aclass, opt, ctx); 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci if (ret <= 0) 170e1051a39Sopenharmony_ci return ret; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci if (*val) 173e1051a39Sopenharmony_ci x509_name_ex_free(val, NULL); 174e1051a39Sopenharmony_ci if (!x509_name_ex_new(&nm.a, NULL)) 175e1051a39Sopenharmony_ci goto err; 176e1051a39Sopenharmony_ci /* We've decoded it: now cache encoding */ 177e1051a39Sopenharmony_ci if (!BUF_MEM_grow(nm.x->bytes, p - q)) 178e1051a39Sopenharmony_ci goto err; 179e1051a39Sopenharmony_ci memcpy(nm.x->bytes->data, q, p - q); 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci /* Convert internal representation to X509_NAME structure */ 182e1051a39Sopenharmony_ci for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { 183e1051a39Sopenharmony_ci entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); 184e1051a39Sopenharmony_ci for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { 185e1051a39Sopenharmony_ci entry = sk_X509_NAME_ENTRY_value(entries, j); 186e1051a39Sopenharmony_ci entry->set = i; 187e1051a39Sopenharmony_ci if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) 188e1051a39Sopenharmony_ci goto err; 189e1051a39Sopenharmony_ci (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci } 192e1051a39Sopenharmony_ci ret = x509_name_canon(nm.x); 193e1051a39Sopenharmony_ci if (!ret) 194e1051a39Sopenharmony_ci goto err; 195e1051a39Sopenharmony_ci sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 196e1051a39Sopenharmony_ci local_sk_X509_NAME_ENTRY_free); 197e1051a39Sopenharmony_ci nm.x->modified = 0; 198e1051a39Sopenharmony_ci *val = nm.a; 199e1051a39Sopenharmony_ci *in = p; 200e1051a39Sopenharmony_ci return ret; 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci err: 203e1051a39Sopenharmony_ci if (nm.x != NULL) 204e1051a39Sopenharmony_ci X509_NAME_free(nm.x); 205e1051a39Sopenharmony_ci sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 206e1051a39Sopenharmony_ci local_sk_X509_NAME_ENTRY_pop_free); 207e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR); 208e1051a39Sopenharmony_ci return 0; 209e1051a39Sopenharmony_ci} 210e1051a39Sopenharmony_ci 211e1051a39Sopenharmony_cistatic int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out, 212e1051a39Sopenharmony_ci const ASN1_ITEM *it, int tag, int aclass) 213e1051a39Sopenharmony_ci{ 214e1051a39Sopenharmony_ci int ret; 215e1051a39Sopenharmony_ci X509_NAME *a = (X509_NAME *)*val; 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci if (a->modified) { 218e1051a39Sopenharmony_ci ret = x509_name_encode(a); 219e1051a39Sopenharmony_ci if (ret < 0) 220e1051a39Sopenharmony_ci return ret; 221e1051a39Sopenharmony_ci ret = x509_name_canon(a); 222e1051a39Sopenharmony_ci if (!ret) 223e1051a39Sopenharmony_ci return -1; 224e1051a39Sopenharmony_ci } 225e1051a39Sopenharmony_ci ret = a->bytes->length; 226e1051a39Sopenharmony_ci if (out != NULL) { 227e1051a39Sopenharmony_ci memcpy(*out, a->bytes->data, ret); 228e1051a39Sopenharmony_ci *out += ret; 229e1051a39Sopenharmony_ci } 230e1051a39Sopenharmony_ci return ret; 231e1051a39Sopenharmony_ci} 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_cistatic int x509_name_encode(X509_NAME *a) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci union { 236e1051a39Sopenharmony_ci STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 237e1051a39Sopenharmony_ci const ASN1_VALUE *a; 238e1051a39Sopenharmony_ci } intname = { 239e1051a39Sopenharmony_ci NULL 240e1051a39Sopenharmony_ci }; 241e1051a39Sopenharmony_ci int len; 242e1051a39Sopenharmony_ci unsigned char *p; 243e1051a39Sopenharmony_ci STACK_OF(X509_NAME_ENTRY) *entries = NULL; 244e1051a39Sopenharmony_ci X509_NAME_ENTRY *entry; 245e1051a39Sopenharmony_ci int i, set = -1; 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 248e1051a39Sopenharmony_ci if (!intname.s) 249e1051a39Sopenharmony_ci goto memerr; 250e1051a39Sopenharmony_ci for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 251e1051a39Sopenharmony_ci entry = sk_X509_NAME_ENTRY_value(a->entries, i); 252e1051a39Sopenharmony_ci if (entry->set != set) { 253e1051a39Sopenharmony_ci entries = sk_X509_NAME_ENTRY_new_null(); 254e1051a39Sopenharmony_ci if (!entries) 255e1051a39Sopenharmony_ci goto memerr; 256e1051a39Sopenharmony_ci if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { 257e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_free(entries); 258e1051a39Sopenharmony_ci goto memerr; 259e1051a39Sopenharmony_ci } 260e1051a39Sopenharmony_ci set = entry->set; 261e1051a39Sopenharmony_ci } 262e1051a39Sopenharmony_ci if (!sk_X509_NAME_ENTRY_push(entries, entry)) 263e1051a39Sopenharmony_ci goto memerr; 264e1051a39Sopenharmony_ci } 265e1051a39Sopenharmony_ci len = ASN1_item_ex_i2d(&intname.a, NULL, 266e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 267e1051a39Sopenharmony_ci if (!BUF_MEM_grow(a->bytes, len)) 268e1051a39Sopenharmony_ci goto memerr; 269e1051a39Sopenharmony_ci p = (unsigned char *)a->bytes->data; 270e1051a39Sopenharmony_ci ASN1_item_ex_i2d(&intname.a, 271e1051a39Sopenharmony_ci &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); 272e1051a39Sopenharmony_ci sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 273e1051a39Sopenharmony_ci local_sk_X509_NAME_ENTRY_free); 274e1051a39Sopenharmony_ci a->modified = 0; 275e1051a39Sopenharmony_ci return len; 276e1051a39Sopenharmony_ci memerr: 277e1051a39Sopenharmony_ci sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 278e1051a39Sopenharmony_ci local_sk_X509_NAME_ENTRY_free); 279e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 280e1051a39Sopenharmony_ci return -1; 281e1051a39Sopenharmony_ci} 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_cistatic int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval, 284e1051a39Sopenharmony_ci int indent, 285e1051a39Sopenharmony_ci const char *fname, const ASN1_PCTX *pctx) 286e1051a39Sopenharmony_ci{ 287e1051a39Sopenharmony_ci if (X509_NAME_print_ex(out, (const X509_NAME *)*pval, 288e1051a39Sopenharmony_ci indent, pctx->nm_flags) <= 0) 289e1051a39Sopenharmony_ci return 0; 290e1051a39Sopenharmony_ci return 2; 291e1051a39Sopenharmony_ci} 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ci/* 294e1051a39Sopenharmony_ci * This function generates the canonical encoding of the Name structure. In 295e1051a39Sopenharmony_ci * it all strings are converted to UTF8, leading, trailing and multiple 296e1051a39Sopenharmony_ci * spaces collapsed, converted to lower case and the leading SEQUENCE header 297e1051a39Sopenharmony_ci * removed. In future we could also normalize the UTF8 too. By doing this 298e1051a39Sopenharmony_ci * comparison of Name structures can be rapidly performed by just using 299e1051a39Sopenharmony_ci * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name 300e1051a39Sopenharmony_ci * constraints of type dirName can also be checked with a simple memcmp(). 301e1051a39Sopenharmony_ci * NOTE: For empty X509_NAME (NULL-DN), canon_enclen == 0 && canon_enc == NULL 302e1051a39Sopenharmony_ci */ 303e1051a39Sopenharmony_ci 304e1051a39Sopenharmony_cistatic int x509_name_canon(X509_NAME *a) 305e1051a39Sopenharmony_ci{ 306e1051a39Sopenharmony_ci unsigned char *p; 307e1051a39Sopenharmony_ci STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname; 308e1051a39Sopenharmony_ci STACK_OF(X509_NAME_ENTRY) *entries = NULL; 309e1051a39Sopenharmony_ci X509_NAME_ENTRY *entry, *tmpentry = NULL; 310e1051a39Sopenharmony_ci int i, set = -1, ret = 0, len; 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci OPENSSL_free(a->canon_enc); 313e1051a39Sopenharmony_ci a->canon_enc = NULL; 314e1051a39Sopenharmony_ci /* Special case: empty X509_NAME => null encoding */ 315e1051a39Sopenharmony_ci if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { 316e1051a39Sopenharmony_ci a->canon_enclen = 0; 317e1051a39Sopenharmony_ci return 1; 318e1051a39Sopenharmony_ci } 319e1051a39Sopenharmony_ci intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 320e1051a39Sopenharmony_ci if (intname == NULL) { 321e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 322e1051a39Sopenharmony_ci goto err; 323e1051a39Sopenharmony_ci } 324e1051a39Sopenharmony_ci for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 325e1051a39Sopenharmony_ci entry = sk_X509_NAME_ENTRY_value(a->entries, i); 326e1051a39Sopenharmony_ci if (entry->set != set) { 327e1051a39Sopenharmony_ci entries = sk_X509_NAME_ENTRY_new_null(); 328e1051a39Sopenharmony_ci if (entries == NULL) 329e1051a39Sopenharmony_ci goto err; 330e1051a39Sopenharmony_ci if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { 331e1051a39Sopenharmony_ci sk_X509_NAME_ENTRY_free(entries); 332e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 333e1051a39Sopenharmony_ci goto err; 334e1051a39Sopenharmony_ci } 335e1051a39Sopenharmony_ci set = entry->set; 336e1051a39Sopenharmony_ci } 337e1051a39Sopenharmony_ci tmpentry = X509_NAME_ENTRY_new(); 338e1051a39Sopenharmony_ci if (tmpentry == NULL) { 339e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 340e1051a39Sopenharmony_ci goto err; 341e1051a39Sopenharmony_ci } 342e1051a39Sopenharmony_ci tmpentry->object = OBJ_dup(entry->object); 343e1051a39Sopenharmony_ci if (tmpentry->object == NULL) { 344e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 345e1051a39Sopenharmony_ci goto err; 346e1051a39Sopenharmony_ci } 347e1051a39Sopenharmony_ci if (!asn1_string_canon(tmpentry->value, entry->value)) 348e1051a39Sopenharmony_ci goto err; 349e1051a39Sopenharmony_ci if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) { 350e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 351e1051a39Sopenharmony_ci goto err; 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci tmpentry = NULL; 354e1051a39Sopenharmony_ci } 355e1051a39Sopenharmony_ci 356e1051a39Sopenharmony_ci /* Finally generate encoding */ 357e1051a39Sopenharmony_ci len = i2d_name_canon(intname, NULL); 358e1051a39Sopenharmony_ci if (len < 0) 359e1051a39Sopenharmony_ci goto err; 360e1051a39Sopenharmony_ci a->canon_enclen = len; 361e1051a39Sopenharmony_ci 362e1051a39Sopenharmony_ci p = OPENSSL_malloc(a->canon_enclen); 363e1051a39Sopenharmony_ci if (p == NULL) { 364e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 365e1051a39Sopenharmony_ci goto err; 366e1051a39Sopenharmony_ci } 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci a->canon_enc = p; 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci i2d_name_canon(intname, &p); 371e1051a39Sopenharmony_ci 372e1051a39Sopenharmony_ci ret = 1; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci err: 375e1051a39Sopenharmony_ci X509_NAME_ENTRY_free(tmpentry); 376e1051a39Sopenharmony_ci sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, 377e1051a39Sopenharmony_ci local_sk_X509_NAME_ENTRY_pop_free); 378e1051a39Sopenharmony_ci return ret; 379e1051a39Sopenharmony_ci} 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci/* Bitmap of all the types of string that will be canonicalized. */ 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci#define ASN1_MASK_CANON \ 384e1051a39Sopenharmony_ci (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ 385e1051a39Sopenharmony_ci | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ 386e1051a39Sopenharmony_ci | B_ASN1_VISIBLESTRING) 387e1051a39Sopenharmony_ci 388e1051a39Sopenharmony_cistatic int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in) 389e1051a39Sopenharmony_ci{ 390e1051a39Sopenharmony_ci unsigned char *to, *from; 391e1051a39Sopenharmony_ci int len, i; 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci /* If type not in bitmask just copy string across */ 394e1051a39Sopenharmony_ci if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { 395e1051a39Sopenharmony_ci if (!ASN1_STRING_copy(out, in)) 396e1051a39Sopenharmony_ci return 0; 397e1051a39Sopenharmony_ci return 1; 398e1051a39Sopenharmony_ci } 399e1051a39Sopenharmony_ci 400e1051a39Sopenharmony_ci out->type = V_ASN1_UTF8STRING; 401e1051a39Sopenharmony_ci out->length = ASN1_STRING_to_UTF8(&out->data, in); 402e1051a39Sopenharmony_ci if (out->length == -1) 403e1051a39Sopenharmony_ci return 0; 404e1051a39Sopenharmony_ci 405e1051a39Sopenharmony_ci to = out->data; 406e1051a39Sopenharmony_ci from = to; 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_ci len = out->length; 409e1051a39Sopenharmony_ci 410e1051a39Sopenharmony_ci /* 411e1051a39Sopenharmony_ci * Convert string in place to canonical form. Ultimately we may need to 412e1051a39Sopenharmony_ci * handle a wider range of characters but for now ignore anything with 413e1051a39Sopenharmony_ci * MSB set and rely on the ossl_isspace() to fail on bad characters without 414e1051a39Sopenharmony_ci * needing isascii or range checks as well. 415e1051a39Sopenharmony_ci */ 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci /* Ignore leading spaces */ 418e1051a39Sopenharmony_ci while (len > 0 && ossl_isspace(*from)) { 419e1051a39Sopenharmony_ci from++; 420e1051a39Sopenharmony_ci len--; 421e1051a39Sopenharmony_ci } 422e1051a39Sopenharmony_ci 423e1051a39Sopenharmony_ci to = from + len; 424e1051a39Sopenharmony_ci 425e1051a39Sopenharmony_ci /* Ignore trailing spaces */ 426e1051a39Sopenharmony_ci while (len > 0 && ossl_isspace(to[-1])) { 427e1051a39Sopenharmony_ci to--; 428e1051a39Sopenharmony_ci len--; 429e1051a39Sopenharmony_ci } 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci to = out->data; 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci i = 0; 434e1051a39Sopenharmony_ci while (i < len) { 435e1051a39Sopenharmony_ci /* If not ASCII set just copy across */ 436e1051a39Sopenharmony_ci if (!ossl_isascii(*from)) { 437e1051a39Sopenharmony_ci *to++ = *from++; 438e1051a39Sopenharmony_ci i++; 439e1051a39Sopenharmony_ci } 440e1051a39Sopenharmony_ci /* Collapse multiple spaces */ 441e1051a39Sopenharmony_ci else if (ossl_isspace(*from)) { 442e1051a39Sopenharmony_ci /* Copy one space across */ 443e1051a39Sopenharmony_ci *to++ = ' '; 444e1051a39Sopenharmony_ci /* 445e1051a39Sopenharmony_ci * Ignore subsequent spaces. Note: don't need to check len here 446e1051a39Sopenharmony_ci * because we know the last character is a non-space so we can't 447e1051a39Sopenharmony_ci * overflow. 448e1051a39Sopenharmony_ci */ 449e1051a39Sopenharmony_ci do { 450e1051a39Sopenharmony_ci from++; 451e1051a39Sopenharmony_ci i++; 452e1051a39Sopenharmony_ci } 453e1051a39Sopenharmony_ci while (ossl_isspace(*from)); 454e1051a39Sopenharmony_ci } else { 455e1051a39Sopenharmony_ci *to++ = ossl_tolower(*from); 456e1051a39Sopenharmony_ci from++; 457e1051a39Sopenharmony_ci i++; 458e1051a39Sopenharmony_ci } 459e1051a39Sopenharmony_ci } 460e1051a39Sopenharmony_ci 461e1051a39Sopenharmony_ci out->length = to - out->data; 462e1051a39Sopenharmony_ci 463e1051a39Sopenharmony_ci return 1; 464e1051a39Sopenharmony_ci 465e1051a39Sopenharmony_ci} 466e1051a39Sopenharmony_ci 467e1051a39Sopenharmony_cistatic int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, 468e1051a39Sopenharmony_ci unsigned char **in) 469e1051a39Sopenharmony_ci{ 470e1051a39Sopenharmony_ci int i, len, ltmp; 471e1051a39Sopenharmony_ci const ASN1_VALUE *v; 472e1051a39Sopenharmony_ci STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ci len = 0; 475e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { 476e1051a39Sopenharmony_ci v = sk_ASN1_VALUE_value(intname, i); 477e1051a39Sopenharmony_ci ltmp = ASN1_item_ex_i2d(&v, in, 478e1051a39Sopenharmony_ci ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); 479e1051a39Sopenharmony_ci if (ltmp < 0) 480e1051a39Sopenharmony_ci return ltmp; 481e1051a39Sopenharmony_ci len += ltmp; 482e1051a39Sopenharmony_ci } 483e1051a39Sopenharmony_ci return len; 484e1051a39Sopenharmony_ci} 485e1051a39Sopenharmony_ci 486e1051a39Sopenharmony_ciint X509_NAME_set(X509_NAME **xn, const X509_NAME *name) 487e1051a39Sopenharmony_ci{ 488e1051a39Sopenharmony_ci X509_NAME *name_copy; 489e1051a39Sopenharmony_ci 490e1051a39Sopenharmony_ci if (*xn == name) 491e1051a39Sopenharmony_ci return *xn != NULL; 492e1051a39Sopenharmony_ci if ((name_copy = X509_NAME_dup(name)) == NULL) 493e1051a39Sopenharmony_ci return 0; 494e1051a39Sopenharmony_ci X509_NAME_free(*xn); 495e1051a39Sopenharmony_ci *xn = name_copy; 496e1051a39Sopenharmony_ci return 1; 497e1051a39Sopenharmony_ci} 498e1051a39Sopenharmony_ci 499e1051a39Sopenharmony_ciint X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) 500e1051a39Sopenharmony_ci{ 501e1051a39Sopenharmony_ci char *s, *c, *b; 502e1051a39Sopenharmony_ci int i; 503e1051a39Sopenharmony_ci 504e1051a39Sopenharmony_ci b = X509_NAME_oneline(name, NULL, 0); 505e1051a39Sopenharmony_ci if (b == NULL) 506e1051a39Sopenharmony_ci return 0; 507e1051a39Sopenharmony_ci if (*b == '\0') { 508e1051a39Sopenharmony_ci OPENSSL_free(b); 509e1051a39Sopenharmony_ci return 1; 510e1051a39Sopenharmony_ci } 511e1051a39Sopenharmony_ci s = b + 1; /* skip the first slash */ 512e1051a39Sopenharmony_ci 513e1051a39Sopenharmony_ci c = s; 514e1051a39Sopenharmony_ci for (;;) { 515e1051a39Sopenharmony_ci if (((*s == '/') && 516e1051a39Sopenharmony_ci (ossl_isupper(s[1]) && ((s[2] == '=') || 517e1051a39Sopenharmony_ci (ossl_isupper(s[2]) && (s[3] == '=')) 518e1051a39Sopenharmony_ci ))) || (*s == '\0')) 519e1051a39Sopenharmony_ci { 520e1051a39Sopenharmony_ci i = s - c; 521e1051a39Sopenharmony_ci if (BIO_write(bp, c, i) != i) 522e1051a39Sopenharmony_ci goto err; 523e1051a39Sopenharmony_ci c = s + 1; /* skip following slash */ 524e1051a39Sopenharmony_ci if (*s != '\0') { 525e1051a39Sopenharmony_ci if (BIO_write(bp, ", ", 2) != 2) 526e1051a39Sopenharmony_ci goto err; 527e1051a39Sopenharmony_ci } 528e1051a39Sopenharmony_ci } 529e1051a39Sopenharmony_ci if (*s == '\0') 530e1051a39Sopenharmony_ci break; 531e1051a39Sopenharmony_ci s++; 532e1051a39Sopenharmony_ci } 533e1051a39Sopenharmony_ci 534e1051a39Sopenharmony_ci OPENSSL_free(b); 535e1051a39Sopenharmony_ci return 1; 536e1051a39Sopenharmony_ci err: 537e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); 538e1051a39Sopenharmony_ci OPENSSL_free(b); 539e1051a39Sopenharmony_ci return 0; 540e1051a39Sopenharmony_ci} 541e1051a39Sopenharmony_ci 542e1051a39Sopenharmony_ciint X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder, 543e1051a39Sopenharmony_ci size_t *pderlen) 544e1051a39Sopenharmony_ci{ 545e1051a39Sopenharmony_ci /* Make sure encoding is valid */ 546e1051a39Sopenharmony_ci if (i2d_X509_NAME(nm, NULL) <= 0) 547e1051a39Sopenharmony_ci return 0; 548e1051a39Sopenharmony_ci if (pder != NULL) 549e1051a39Sopenharmony_ci *pder = (unsigned char *)nm->bytes->data; 550e1051a39Sopenharmony_ci if (pderlen != NULL) 551e1051a39Sopenharmony_ci *pderlen = nm->bytes->length; 552e1051a39Sopenharmony_ci return 1; 553e1051a39Sopenharmony_ci} 554