1 /* v3_sxnet.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4  * 1999.
5  */
6 /* ====================================================================
7  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  *
58  */
59 
60 #include <stdio.h>
61 #include <string.h>
62 
63 #include <openssl/asn1.h>
64 #include <openssl/asn1t.h>
65 #include <openssl/conf.h>
66 #include <openssl/err.h>
67 #include <openssl/mem.h>
68 #include <openssl/obj.h>
69 #include <openssl/x509v3.h>
70 
71 /* Support for Thawte strong extranet extension */
72 
73 #define SXNET_TEST
74 
75 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
76                      int indent);
77 #ifdef SXNET_TEST
78 static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
79                         STACK_OF(CONF_VALUE) *nval);
80 #endif
81 const X509V3_EXT_METHOD v3_sxnet = {
82     NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
83     0, 0, 0, 0,
84     0, 0,
85     0,
86 #ifdef SXNET_TEST
87     (X509V3_EXT_V2I)sxnet_v2i,
88 #else
89     0,
90 #endif
91     (X509V3_EXT_I2R)sxnet_i2r,
92     0,
93     NULL
94 };
95 
96 ASN1_SEQUENCE(SXNETID) = {
97         ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
98         ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
99 } ASN1_SEQUENCE_END(SXNETID)
100 
101 IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
102 
103 ASN1_SEQUENCE(SXNET) = {
104         ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
105         ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
106 } ASN1_SEQUENCE_END(SXNET)
107 
108 IMPLEMENT_ASN1_FUNCTIONS(SXNET)
109 
110 static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
111                      int indent)
112 {
113     long v;
114     char *tmp;
115     SXNETID *id;
116     size_t i;
117     v = ASN1_INTEGER_get(sx->version);
118     BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
119     for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
120         id = sk_SXNETID_value(sx->ids, i);
121         tmp = i2s_ASN1_INTEGER(NULL, id->zone);
122         BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
123         OPENSSL_free(tmp);
124         M_ASN1_OCTET_STRING_print(out, id->user);
125     }
126     return 1;
127 }
128 
129 #ifdef SXNET_TEST
130 
131 /*
132  * NBB: this is used for testing only. It should *not* be used for anything
133  * else because it will just take static IDs from the configuration file and
134  * they should really be separate values for each user.
135  */
136 
sxnet_v2i(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)137 static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
138                         STACK_OF(CONF_VALUE) *nval)
139 {
140     CONF_VALUE *cnf;
141     SXNET *sx = NULL;
142     size_t i;
143     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
144         cnf = sk_CONF_VALUE_value(nval, i);
145         if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
146             return NULL;
147     }
148     return sx;
149 }
150 
151 #endif
152 
153 /* Strong Extranet utility functions */
154 
155 /* Add an id given the zone as an ASCII number */
156 
SXNET_add_id_asc(SXNET ** psx,char * zone,char * user,int userlen)157 int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
158 {
159     ASN1_INTEGER *izone = NULL;
160     if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
161         OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
162         return 0;
163     }
164     return SXNET_add_id_INTEGER(psx, izone, user, userlen);
165 }
166 
167 /* Add an id given the zone as an unsigned long */
168 
SXNET_add_id_ulong(SXNET ** psx,unsigned long lzone,char * user,int userlen)169 int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
170                        int userlen)
171 {
172     ASN1_INTEGER *izone = NULL;
173     if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
174         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
175         M_ASN1_INTEGER_free(izone);
176         return 0;
177     }
178     return SXNET_add_id_INTEGER(psx, izone, user, userlen);
179 
180 }
181 
182 /*
183  * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
184  * passed integer and doesn't make a copy so don't free it up afterwards.
185  */
186 
SXNET_add_id_INTEGER(SXNET ** psx,ASN1_INTEGER * zone,char * user,int userlen)187 int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
188                          int userlen)
189 {
190     SXNET *sx = NULL;
191     SXNETID *id = NULL;
192     if (!psx || !zone || !user) {
193         OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
194         return 0;
195     }
196     if (userlen == -1)
197         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()))
204             goto err;
205         if (!ASN1_INTEGER_set(sx->version, 0))
206             goto err;
207         *psx = sx;
208     } else
209         sx = *psx;
210     if (SXNET_get_id_INTEGER(sx, zone)) {
211         OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
212         return 0;
213     }
214 
215     if (!(id = SXNETID_new()))
216         goto err;
217     if (userlen == -1)
218         userlen = strlen(user);
219 
220     if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
221         goto err;
222     if (!sk_SXNETID_push(sx->ids, id))
223         goto err;
224     id->zone = zone;
225     return 1;
226 
227  err:
228     OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
229     SXNETID_free(id);
230     SXNET_free(sx);
231     *psx = NULL;
232     return 0;
233 }
234 
SXNET_get_id_asc(SXNET * sx,char * zone)235 ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
236 {
237     ASN1_INTEGER *izone = NULL;
238     ASN1_OCTET_STRING *oct;
239     if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
240         OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
241         return NULL;
242     }
243     oct = SXNET_get_id_INTEGER(sx, izone);
244     M_ASN1_INTEGER_free(izone);
245     return oct;
246 }
247 
SXNET_get_id_ulong(SXNET * sx,unsigned long lzone)248 ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
249 {
250     ASN1_INTEGER *izone = NULL;
251     ASN1_OCTET_STRING *oct;
252     if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
253         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
254         M_ASN1_INTEGER_free(izone);
255         return NULL;
256     }
257     oct = SXNET_get_id_INTEGER(sx, izone);
258     M_ASN1_INTEGER_free(izone);
259     return oct;
260 }
261 
SXNET_get_id_INTEGER(SXNET * sx,ASN1_INTEGER * zone)262 ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
263 {
264     SXNETID *id;
265     size_t i;
266     for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
267         id = sk_SXNETID_value(sx->ids, i);
268         if (!M_ASN1_INTEGER_cmp(id->zone, zone))
269             return id->user;
270     }
271     return NULL;
272 }
273 
274 IMPLEMENT_ASN1_SET_OF(SXNETID)
275