1/* v3_sxnet.c */ 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 <stdio.h> 60#include <string.h> 61 62#include <openssl/asn1.h> 63#include <openssl/asn1t.h> 64#include <openssl/conf.h> 65#include <openssl/err.h> 66#include <openssl/mem.h> 67#include <openssl/obj.h> 68#include <openssl/x509v3.h> 69 70 71/* Support for Thawte strong extranet extension */ 72 73#define SXNET_TEST 74 75static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent); 76#ifdef SXNET_TEST 77static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 78 STACK_OF(CONF_VALUE) *nval); 79#endif 80const X509V3_EXT_METHOD v3_sxnet = { 81NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), 820,0,0,0, 830,0, 840, 85#ifdef SXNET_TEST 86(X509V3_EXT_V2I)sxnet_v2i, 87#else 880, 89#endif 90(X509V3_EXT_I2R)sxnet_i2r, 910, 92NULL 93}; 94 95ASN1_SEQUENCE(SXNETID) = { 96 ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), 97 ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) 98} ASN1_SEQUENCE_END(SXNETID) 99 100IMPLEMENT_ASN1_FUNCTIONS(SXNETID) 101 102ASN1_SEQUENCE(SXNET) = { 103 ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), 104 ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) 105} ASN1_SEQUENCE_END(SXNET) 106 107IMPLEMENT_ASN1_FUNCTIONS(SXNET) 108 109static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, 110 int indent) 111{ 112 long v; 113 char *tmp; 114 SXNETID *id; 115 size_t i; 116 v = ASN1_INTEGER_get(sx->version); 117 BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); 118 for(i = 0; i < sk_SXNETID_num(sx->ids); i++) { 119 id = sk_SXNETID_value(sx->ids, i); 120 tmp = i2s_ASN1_INTEGER(NULL, id->zone); 121 BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); 122 OPENSSL_free(tmp); 123 M_ASN1_OCTET_STRING_print(out, id->user); 124 } 125 return 1; 126} 127 128#ifdef SXNET_TEST 129 130/* NBB: this is used for testing only. It should *not* be used for anything 131 * else because it will just take static IDs from the configuration file and 132 * they should really be separate values for each user. 133 */ 134 135 136static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, 137 STACK_OF(CONF_VALUE) *nval) 138{ 139 CONF_VALUE *cnf; 140 SXNET *sx = NULL; 141 size_t i; 142 for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { 143 cnf = sk_CONF_VALUE_value(nval, i); 144 if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) 145 return NULL; 146 } 147 return sx; 148} 149 150 151#endif 152 153/* Strong Extranet utility functions */ 154 155/* Add an id given the zone as an ASCII number */ 156 157int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, 158 int userlen) 159{ 160 ASN1_INTEGER *izone = NULL; 161 if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) { 162 OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 163 return 0; 164 } 165 return SXNET_add_id_INTEGER(psx, izone, user, userlen); 166} 167 168/* Add an id given the zone as an unsigned long */ 169 170int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, 171 int userlen) 172{ 173 ASN1_INTEGER *izone = NULL; 174 if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { 175 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); 176 M_ASN1_INTEGER_free(izone); 177 return 0; 178 } 179 return SXNET_add_id_INTEGER(psx, izone, user, userlen); 180 181} 182 183/* Add an id given the zone as an ASN1_INTEGER. 184 * Note this version uses the passed integer and doesn't make a copy so don't 185 * free it up afterwards. 186 */ 187 188int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, 189 int userlen) 190{ 191 SXNET *sx = NULL; 192 SXNETID *id = NULL; 193 if(!psx || !zone || !user) { 194 OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); 195 return 0; 196 } 197 if(userlen == -1) userlen = strlen(user); 198 if(userlen > 64) { 199 OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG); 200 return 0; 201 } 202 if(!*psx) { 203 if(!(sx = SXNET_new())) goto err; 204 if(!ASN1_INTEGER_set(sx->version, 0)) goto err; 205 *psx = sx; 206 } else sx = *psx; 207 if(SXNET_get_id_INTEGER(sx, zone)) { 208 OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID); 209 return 0; 210 } 211 212 if(!(id = SXNETID_new())) goto err; 213 if(userlen == -1) userlen = strlen(user); 214 215 if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err; 216 if(!sk_SXNETID_push(sx->ids, id)) goto err; 217 id->zone = zone; 218 return 1; 219 220 err: 221 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); 222 SXNETID_free(id); 223 SXNET_free(sx); 224 *psx = NULL; 225 return 0; 226} 227 228ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone) 229{ 230 ASN1_INTEGER *izone = NULL; 231 ASN1_OCTET_STRING *oct; 232 if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) { 233 OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE); 234 return NULL; 235 } 236 oct = SXNET_get_id_INTEGER(sx, izone); 237 M_ASN1_INTEGER_free(izone); 238 return oct; 239} 240 241ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) 242{ 243 ASN1_INTEGER *izone = NULL; 244 ASN1_OCTET_STRING *oct; 245 if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { 246 OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); 247 M_ASN1_INTEGER_free(izone); 248 return NULL; 249 } 250 oct = SXNET_get_id_INTEGER(sx, izone); 251 M_ASN1_INTEGER_free(izone); 252 return oct; 253} 254 255ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) 256{ 257 SXNETID *id; 258 size_t i; 259 for(i = 0; i < sk_SXNETID_num(sx->ids); i++) { 260 id = sk_SXNETID_value(sx->ids, i); 261 if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user; 262 } 263 return NULL; 264} 265 266IMPLEMENT_ASN1_SET_OF(SXNETID) 267