1 /* $OpenBSD: a_strnid.c,v 1.29 2023/12/16 12:56:20 tb Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 1999. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 #include <errno.h> 60 #include <limits.h> 61 #include <stdlib.h> 62 #include <string.h> 63 64 #include <openssl/asn1.h> 65 #include <openssl/err.h> 66 #include <openssl/objects.h> 67 68 /* 69 * XXX - unprotected global state 70 * 71 * This is the global mask for the mbstring functions: this is used to 72 * mask out certain types (such as BMPString and UTF8String) because 73 * certain software (e.g. Netscape) has problems with them. 74 */ 75 static unsigned long global_mask = B_ASN1_UTF8STRING; 76 77 void 78 ASN1_STRING_set_default_mask(unsigned long mask) 79 { 80 global_mask = mask; 81 } 82 LCRYPTO_ALIAS(ASN1_STRING_set_default_mask); 83 84 unsigned long 85 ASN1_STRING_get_default_mask(void) 86 { 87 return global_mask; 88 } 89 LCRYPTO_ALIAS(ASN1_STRING_get_default_mask); 90 91 /* 92 * This function sets the default to various "flavours" of configuration 93 * based on an ASCII string. Currently this is: 94 * MASK:XXXX : a numerical mask value. 95 * nobmp : Don't use BMPStrings (just Printable, T61). 96 * pkix : PKIX recommendation in RFC2459. 97 * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004). 98 * default: the default value, Printable, T61, BMP. 99 */ 100 101 int 102 ASN1_STRING_set_default_mask_asc(const char *p) 103 { 104 unsigned long mask; 105 char *end; 106 int save_errno; 107 108 if (strncmp(p, "MASK:", 5) == 0) { 109 if (p[5] == '\0') 110 return 0; 111 save_errno = errno; 112 errno = 0; 113 mask = strtoul(p + 5, &end, 0); 114 if (errno == ERANGE && mask == ULONG_MAX) 115 return 0; 116 errno = save_errno; 117 if (*end != '\0') 118 return 0; 119 } else if (strcmp(p, "nombstr") == 0) 120 mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)); 121 else if (strcmp(p, "pkix") == 0) 122 mask = ~((unsigned long)B_ASN1_T61STRING); 123 else if (strcmp(p, "utf8only") == 0) 124 mask = B_ASN1_UTF8STRING; 125 else if (strcmp(p, "default") == 0) 126 mask = 0xFFFFFFFFL; 127 else 128 return 0; 129 ASN1_STRING_set_default_mask(mask); 130 return 1; 131 } 132 LCRYPTO_ALIAS(ASN1_STRING_set_default_mask_asc); 133 134 /* 135 * The following function generates an ASN1_STRING based on limits in a table. 136 * Frequently the types and length of an ASN1_STRING are restricted by a 137 * corresponding OID. For example certificates and certificate requests. 138 */ 139 140 ASN1_STRING * 141 ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen, 142 int inform, int nid) 143 { 144 ASN1_STRING_TABLE *tbl; 145 ASN1_STRING *str = NULL; 146 unsigned long mask; 147 int ret; 148 149 if (out == NULL) 150 out = &str; 151 tbl = ASN1_STRING_TABLE_get(nid); 152 if (tbl != NULL) { 153 mask = tbl->mask; 154 if ((tbl->flags & STABLE_NO_MASK) == 0) 155 mask &= global_mask; 156 ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask, 157 tbl->minsize, tbl->maxsize); 158 } else 159 ret = ASN1_mbstring_copy(out, in, inlen, inform, 160 DIRSTRING_TYPE & global_mask); 161 if (ret <= 0) 162 return NULL; 163 return *out; 164 } 165 LCRYPTO_ALIAS(ASN1_STRING_set_by_NID); 166 167 /* From RFC 5280, Appendix A.1. */ 168 #define ub_name 32768 169 #define ub_common_name 64 170 #define ub_locality_name 128 171 #define ub_state_name 128 172 #define ub_organization_name 64 173 #define ub_organization_unit_name 64 174 #define ub_title 64 175 #define ub_email_address 128 /* XXX - bumped to 255 in RFC 5280 */ 176 #define ub_serial_number 64 177 178 static const ASN1_STRING_TABLE tbl_standard[] = { 179 { 180 .nid = NID_commonName, 181 .minsize = 1, 182 .maxsize = ub_common_name, 183 .mask = DIRSTRING_TYPE, 184 .flags = 0, 185 }, 186 { 187 .nid = NID_countryName, 188 .minsize = 2, 189 .maxsize = 2, 190 .mask = B_ASN1_PRINTABLESTRING, 191 .flags = STABLE_NO_MASK, 192 }, 193 { 194 .nid = NID_localityName, 195 .minsize = 1, 196 .maxsize = ub_locality_name, 197 .mask = DIRSTRING_TYPE, 198 .flags = 0, 199 }, 200 { 201 .nid = NID_stateOrProvinceName, 202 .minsize = 1, 203 .maxsize = ub_state_name, 204 .mask = DIRSTRING_TYPE, 205 .flags = 0, 206 }, 207 { 208 .nid = NID_organizationName, 209 .minsize = 1, 210 .maxsize = ub_organization_name, 211 .mask = DIRSTRING_TYPE, 212 .flags = 0, 213 }, 214 { 215 .nid = NID_organizationalUnitName, 216 .minsize = 1, 217 .maxsize = ub_organization_unit_name, 218 .mask = DIRSTRING_TYPE, 219 .flags = 0, 220 }, 221 { 222 .nid = NID_pkcs9_emailAddress, 223 .minsize = 1, 224 .maxsize = ub_email_address, 225 .mask = B_ASN1_IA5STRING, 226 .flags = STABLE_NO_MASK, 227 }, 228 { 229 .nid = NID_pkcs9_unstructuredName, 230 .minsize = 1, 231 .maxsize = -1, 232 .mask = PKCS9STRING_TYPE, 233 .flags = 0, 234 }, 235 { 236 .nid = NID_pkcs9_challengePassword, 237 .minsize = 1, 238 .maxsize = -1, 239 .mask = PKCS9STRING_TYPE, 240 .flags = 0, 241 }, 242 { 243 .nid = NID_pkcs9_unstructuredAddress, 244 .minsize = 1, 245 .maxsize = -1, 246 .mask = DIRSTRING_TYPE, 247 .flags = 0, 248 }, 249 { 250 .nid = NID_givenName, 251 .minsize = 1, 252 .maxsize = ub_name, 253 .mask = DIRSTRING_TYPE, 254 .flags = 0, 255 }, 256 { 257 .nid = NID_surname, 258 .minsize = 1, 259 .maxsize = ub_name, 260 .mask = DIRSTRING_TYPE, 261 .flags = 0, 262 }, 263 { 264 .nid = NID_initials, 265 .minsize = 1, 266 .maxsize = ub_name, 267 .mask = DIRSTRING_TYPE, 268 .flags = 0, 269 }, 270 { 271 .nid = NID_serialNumber, 272 .minsize = 1, 273 .maxsize = ub_serial_number, 274 .mask = B_ASN1_PRINTABLESTRING, 275 .flags = STABLE_NO_MASK, 276 }, 277 { 278 .nid = NID_friendlyName, 279 .minsize = -1, 280 .maxsize = -1, 281 .mask = B_ASN1_BMPSTRING, 282 .flags = STABLE_NO_MASK, 283 }, 284 { 285 .nid = NID_name, 286 .minsize = 1, 287 .maxsize = ub_name, 288 .mask = DIRSTRING_TYPE, 289 .flags = 0, 290 }, 291 { 292 .nid = NID_dnQualifier, 293 .minsize = -1, 294 .maxsize = -1, 295 .mask = B_ASN1_PRINTABLESTRING, 296 .flags = STABLE_NO_MASK, 297 }, 298 { 299 .nid = NID_domainComponent, 300 .minsize = 1, 301 .maxsize = -1, 302 .mask = B_ASN1_IA5STRING, 303 .flags = STABLE_NO_MASK, 304 }, 305 { 306 .nid = NID_ms_csp_name, 307 .minsize = -1, 308 .maxsize = -1, 309 .mask = B_ASN1_BMPSTRING, 310 .flags = STABLE_NO_MASK, 311 }, 312 }; 313 314 #define N_STRING_TABLE_ENTRIES (sizeof(tbl_standard) / sizeof(tbl_standard[0])) 315 316 /* XXX - const */ 317 ASN1_STRING_TABLE * 318 ASN1_STRING_TABLE_get(int nid) 319 { 320 size_t i; 321 322 for (i = 0; i < N_STRING_TABLE_ENTRIES; i++) { 323 const ASN1_STRING_TABLE *entry = &tbl_standard[i]; 324 if (entry->nid == nid) 325 return (ASN1_STRING_TABLE *)entry; 326 } 327 328 return NULL; 329 } 330 LCRYPTO_ALIAS(ASN1_STRING_TABLE_get); 331 332 int 333 ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask, 334 unsigned long flags) 335 { 336 ASN1error(ERR_R_DISABLED); 337 return 0; 338 } 339 LCRYPTO_ALIAS(ASN1_STRING_TABLE_add); 340 341 void 342 ASN1_STRING_TABLE_cleanup(void) 343 { 344 ASN1error(ERR_R_DISABLED); 345 } 346 LCRYPTO_ALIAS(ASN1_STRING_TABLE_cleanup); 347