1 /* 2 * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/conf.h> 13 #include <openssl/asn1.h> 14 #include <openssl/asn1t.h> 15 #include <openssl/x509v3.h> 16 #include "ext_dat.h" 17 18 /* Support for Thawte strong extranet extension */ 19 20 #define SXNET_TEST 21 22 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, 23 int indent); 24 #ifdef SXNET_TEST 25 static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 26 STACK_OF(CONF_VALUE) *nval); 27 #endif 28 const X509V3_EXT_METHOD ossl_v3_sxnet = { 29 NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), 30 0, 0, 0, 0, 31 0, 0, 32 0, 33 #ifdef SXNET_TEST 34 (X509V3_EXT_V2I)sxnet_v2i, 35 #else 36 0, 37 #endif 38 (X509V3_EXT_I2R)sxnet_i2r, 39 0, 40 NULL 41 }; 42 43 ASN1_SEQUENCE(SXNETID) = { 44 ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), 45 ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) 46 } ASN1_SEQUENCE_END(SXNETID) 47 48 IMPLEMENT_ASN1_FUNCTIONS(SXNETID) 49 50 ASN1_SEQUENCE(SXNET) = { 51 ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), 52 ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) 53 } ASN1_SEQUENCE_END(SXNET) 54 55 IMPLEMENT_ASN1_FUNCTIONS(SXNET) 56 57 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, 58 int indent) 59 { 60 int64_t v; 61 char *tmp; 62 SXNETID *id; 63 int i; 64 65 /* 66 * Since we add 1 to the version number to display it, we don't support 67 * LONG_MAX since that would cause on overflow. 68 */ 69 if (!ASN1_INTEGER_get_int64(&v, sx->version) 70 || v >= LONG_MAX 71 || v < LONG_MIN) { 72 BIO_printf(out, "%*sVersion: <unsupported>", indent, ""); 73 } else { 74 long vl = (long)v; 75 76 BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", vl + 1, vl); 77 } 78 for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { 79 id = sk_SXNETID_value(sx->ids, i); 80 tmp = i2s_ASN1_INTEGER(NULL, id->zone); 81 if (tmp == NULL) 82 return 0; 83 BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); 84 OPENSSL_free(tmp); 85 ASN1_STRING_print(out, id->user); 86 } 87 return 1; 88 } 89 90 #ifdef SXNET_TEST 91 92 /* 93 * NBB: this is used for testing only. It should *not* be used for anything 94 * else because it will just take static IDs from the configuration file and 95 * they should really be separate values for each user. 96 */ 97 98 static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 99 STACK_OF(CONF_VALUE) *nval) 100 { 101 CONF_VALUE *cnf; 102 SXNET *sx = NULL; 103 int i; 104 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 105 cnf = sk_CONF_VALUE_value(nval, i); 106 if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) 107 return NULL; 108 } 109 return sx; 110 } 111 112 #endif 113 114 /* Strong Extranet utility functions */ 115 116 /* Add an id given the zone as an ASCII number */ 117 118 int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen) 119 { 120 ASN1_INTEGER *izone; 121 122 if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { 123 ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 124 return 0; 125 } 126 return SXNET_add_id_INTEGER(psx, izone, user, userlen); 127 } 128 129 /* Add an id given the zone as an unsigned long */ 130 131 int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, 132 int userlen) 133 { 134 ASN1_INTEGER *izone; 135 136 if ((izone = ASN1_INTEGER_new()) == NULL 137 || !ASN1_INTEGER_set(izone, lzone)) { 138 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 139 ASN1_INTEGER_free(izone); 140 return 0; 141 } 142 return SXNET_add_id_INTEGER(psx, izone, user, userlen); 143 144 } 145 146 /* 147 * Add an id given the zone as an ASN1_INTEGER. Note this version uses the 148 * passed integer and doesn't make a copy so don't free it up afterwards. 149 */ 150 151 int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, 152 int userlen) 153 { 154 SXNET *sx = NULL; 155 SXNETID *id = NULL; 156 157 if (psx == NULL || zone == NULL || user == NULL) { 158 ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT); 159 return 0; 160 } 161 if (userlen == -1) 162 userlen = strlen(user); 163 if (userlen > 64) { 164 ERR_raise(ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG); 165 return 0; 166 } 167 if (*psx == NULL) { 168 if ((sx = SXNET_new()) == NULL) 169 goto err; 170 if (!ASN1_INTEGER_set(sx->version, 0)) 171 goto err; 172 } else 173 sx = *psx; 174 if (SXNET_get_id_INTEGER(sx, zone)) { 175 ERR_raise(ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID); 176 if (*psx == NULL) 177 SXNET_free(sx); 178 return 0; 179 } 180 181 if ((id = SXNETID_new()) == NULL) 182 goto err; 183 if (userlen == -1) 184 userlen = strlen(user); 185 186 if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen)) 187 goto err; 188 if (!sk_SXNETID_push(sx->ids, id)) 189 goto err; 190 id->zone = zone; 191 *psx = sx; 192 return 1; 193 194 err: 195 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 196 SXNETID_free(id); 197 if (*psx == NULL) 198 SXNET_free(sx); 199 return 0; 200 } 201 202 ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone) 203 { 204 ASN1_INTEGER *izone; 205 ASN1_OCTET_STRING *oct; 206 207 if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { 208 ERR_raise(ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 209 return NULL; 210 } 211 oct = SXNET_get_id_INTEGER(sx, izone); 212 ASN1_INTEGER_free(izone); 213 return oct; 214 } 215 216 ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) 217 { 218 ASN1_INTEGER *izone; 219 ASN1_OCTET_STRING *oct; 220 221 if ((izone = ASN1_INTEGER_new()) == NULL 222 || !ASN1_INTEGER_set(izone, lzone)) { 223 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 224 ASN1_INTEGER_free(izone); 225 return NULL; 226 } 227 oct = SXNET_get_id_INTEGER(sx, izone); 228 ASN1_INTEGER_free(izone); 229 return oct; 230 } 231 232 ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) 233 { 234 SXNETID *id; 235 int i; 236 for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { 237 id = sk_SXNETID_value(sx->ids, i); 238 if (!ASN1_INTEGER_cmp(id->zone, zone)) 239 return id->user; 240 } 241 return NULL; 242 } 243