155714Skris/* v3_sxnet.c */
2296465Sdelphij/*
3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4296465Sdelphij * 1999.
555714Skris */
655714Skris/* ====================================================================
755714Skris * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
855714Skris *
955714Skris * Redistribution and use in source and binary forms, with or without
1055714Skris * modification, are permitted provided that the following conditions
1155714Skris * are met:
1255714Skris *
1355714Skris * 1. Redistributions of source code must retain the above copyright
14296465Sdelphij *    notice, this list of conditions and the following disclaimer.
1555714Skris *
1655714Skris * 2. Redistributions in binary form must reproduce the above copyright
1755714Skris *    notice, this list of conditions and the following disclaimer in
1855714Skris *    the documentation and/or other materials provided with the
1955714Skris *    distribution.
2055714Skris *
2155714Skris * 3. All advertising materials mentioning features or use of this
2255714Skris *    software must display the following acknowledgment:
2355714Skris *    "This product includes software developed by the OpenSSL Project
2455714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2555714Skris *
2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2755714Skris *    endorse or promote products derived from this software without
2855714Skris *    prior written permission. For written permission, please contact
2955714Skris *    licensing@OpenSSL.org.
3055714Skris *
3155714Skris * 5. Products derived from this software may not be called "OpenSSL"
3255714Skris *    nor may "OpenSSL" appear in their names without prior written
3355714Skris *    permission of the OpenSSL Project.
3455714Skris *
3555714Skris * 6. Redistributions of any form whatsoever must retain the following
3655714Skris *    acknowledgment:
3755714Skris *    "This product includes software developed by the OpenSSL Project
3855714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3955714Skris *
4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4355714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5255714Skris * ====================================================================
5355714Skris *
5455714Skris * This product includes cryptographic software written by Eric Young
5555714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5655714Skris * Hudson (tjh@cryptsoft.com).
5755714Skris *
5855714Skris */
5955714Skris
6055714Skris#include <stdio.h>
6155714Skris#include "cryptlib.h"
6255714Skris#include <openssl/conf.h>
6355714Skris#include <openssl/asn1.h>
64109998Smarkm#include <openssl/asn1t.h>
6555714Skris#include <openssl/x509v3.h>
6655714Skris
6755714Skris/* Support for Thawte strong extranet extension */
6855714Skris
6955714Skris#define SXNET_TEST
7055714Skris
71296465Sdelphijstatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
72296465Sdelphij                     int indent);
7355714Skris#ifdef SXNET_TEST
74296465Sdelphijstatic SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
75296465Sdelphij                        STACK_OF(CONF_VALUE) *nval);
7655714Skris#endif
77167612Ssimonconst X509V3_EXT_METHOD v3_sxnet = {
78296465Sdelphij    NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
79296465Sdelphij    0, 0, 0, 0,
80296465Sdelphij    0, 0,
81296465Sdelphij    0,
8255714Skris#ifdef SXNET_TEST
83296465Sdelphij    (X509V3_EXT_V2I)sxnet_v2i,
8455714Skris#else
85296465Sdelphij    0,
8655714Skris#endif
87296465Sdelphij    (X509V3_EXT_I2R)sxnet_i2r,
88296465Sdelphij    0,
89296465Sdelphij    NULL
9055714Skris};
9155714Skris
92109998SmarkmASN1_SEQUENCE(SXNETID) = {
93296465Sdelphij        ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
94296465Sdelphij        ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
95109998Smarkm} ASN1_SEQUENCE_END(SXNETID)
9655714Skris
97109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(SXNETID)
9855714Skris
99109998SmarkmASN1_SEQUENCE(SXNET) = {
100296465Sdelphij        ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
101296465Sdelphij        ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
102109998Smarkm} ASN1_SEQUENCE_END(SXNET)
10355714Skris
104109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(SXNET)
10555714Skris
10655714Skrisstatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
107296465Sdelphij                     int indent)
10855714Skris{
109296465Sdelphij    long v;
110296465Sdelphij    char *tmp;
111296465Sdelphij    SXNETID *id;
112296465Sdelphij    int i;
113296465Sdelphij    v = ASN1_INTEGER_get(sx->version);
114296465Sdelphij    BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
115296465Sdelphij    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
116296465Sdelphij        id = sk_SXNETID_value(sx->ids, i);
117296465Sdelphij        tmp = i2s_ASN1_INTEGER(NULL, id->zone);
118296465Sdelphij        BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
119296465Sdelphij        OPENSSL_free(tmp);
120296465Sdelphij        M_ASN1_OCTET_STRING_print(out, id->user);
121296465Sdelphij    }
122296465Sdelphij    return 1;
12355714Skris}
12455714Skris
12555714Skris#ifdef SXNET_TEST
12655714Skris
127296465Sdelphij/*
128296465Sdelphij * NBB: this is used for testing only. It should *not* be used for anything
12955714Skris * else because it will just take static IDs from the configuration file and
13055714Skris * they should really be separate values for each user.
13155714Skris */
13255714Skris
133296465Sdelphijstatic SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
134296465Sdelphij                        STACK_OF(CONF_VALUE) *nval)
13555714Skris{
136296465Sdelphij    CONF_VALUE *cnf;
137296465Sdelphij    SXNET *sx = NULL;
138296465Sdelphij    int i;
139296465Sdelphij    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
140296465Sdelphij        cnf = sk_CONF_VALUE_value(nval, i);
141296465Sdelphij        if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
142296465Sdelphij            return NULL;
143296465Sdelphij    }
144296465Sdelphij    return sx;
14555714Skris}
146296465Sdelphij
14755714Skris#endif
14855714Skris
14955714Skris/* Strong Extranet utility functions */
15055714Skris
15155714Skris/* Add an id given the zone as an ASCII number */
15255714Skris
153296465Sdelphijint SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen)
15455714Skris{
155296465Sdelphij    ASN1_INTEGER *izone = NULL;
156296465Sdelphij    if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
157296465Sdelphij        X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
158296465Sdelphij        return 0;
159296465Sdelphij    }
160296465Sdelphij    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
16155714Skris}
16255714Skris
16355714Skris/* Add an id given the zone as an unsigned long */
16455714Skris
16555714Skrisint SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
166296465Sdelphij                       int userlen)
16755714Skris{
168296465Sdelphij    ASN1_INTEGER *izone = NULL;
169296465Sdelphij    if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
170296465Sdelphij        X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE);
171296465Sdelphij        M_ASN1_INTEGER_free(izone);
172296465Sdelphij        return 0;
173296465Sdelphij    }
174296465Sdelphij    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
175296465Sdelphij
17655714Skris}
17755714Skris
178296465Sdelphij/*
179296465Sdelphij * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
180296465Sdelphij * passed integer and doesn't make a copy so don't free it up afterwards.
18155714Skris */
18255714Skris
18355714Skrisint SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
184296465Sdelphij                         int userlen)
18555714Skris{
186296465Sdelphij    SXNET *sx = NULL;
187296465Sdelphij    SXNETID *id = NULL;
188296465Sdelphij    if (!psx || !zone || !user) {
189296465Sdelphij        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,
190296465Sdelphij                  X509V3_R_INVALID_NULL_ARGUMENT);
191296465Sdelphij        return 0;
192296465Sdelphij    }
193296465Sdelphij    if (userlen == -1)
194296465Sdelphij        userlen = strlen(user);
195296465Sdelphij    if (userlen > 64) {
196296465Sdelphij        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG);
197296465Sdelphij        return 0;
198296465Sdelphij    }
199296465Sdelphij    if (!*psx) {
200296465Sdelphij        if (!(sx = SXNET_new()))
201296465Sdelphij            goto err;
202296465Sdelphij        if (!ASN1_INTEGER_set(sx->version, 0))
203296465Sdelphij            goto err;
204296465Sdelphij        *psx = sx;
205296465Sdelphij    } else
206296465Sdelphij        sx = *psx;
207296465Sdelphij    if (SXNET_get_id_INTEGER(sx, zone)) {
208296465Sdelphij        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
209296465Sdelphij        return 0;
210296465Sdelphij    }
21155714Skris
212296465Sdelphij    if (!(id = SXNETID_new()))
213296465Sdelphij        goto err;
214296465Sdelphij    if (userlen == -1)
215296465Sdelphij        userlen = strlen(user);
216296465Sdelphij
217296465Sdelphij    if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen))
218296465Sdelphij        goto err;
219296465Sdelphij    if (!sk_SXNETID_push(sx->ids, id))
220296465Sdelphij        goto err;
221296465Sdelphij    id->zone = zone;
222296465Sdelphij    return 1;
223296465Sdelphij
224296465Sdelphij err:
225296465Sdelphij    X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE);
226296465Sdelphij    SXNETID_free(id);
227296465Sdelphij    SXNET_free(sx);
228296465Sdelphij    *psx = NULL;
229296465Sdelphij    return 0;
23055714Skris}
23155714Skris
23255714SkrisASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
23355714Skris{
234296465Sdelphij    ASN1_INTEGER *izone = NULL;
235296465Sdelphij    ASN1_OCTET_STRING *oct;
236296465Sdelphij    if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
237296465Sdelphij        X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
238296465Sdelphij        return NULL;
239296465Sdelphij    }
240296465Sdelphij    oct = SXNET_get_id_INTEGER(sx, izone);
241296465Sdelphij    M_ASN1_INTEGER_free(izone);
242296465Sdelphij    return oct;
24355714Skris}
24455714Skris
24555714SkrisASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
24655714Skris{
247296465Sdelphij    ASN1_INTEGER *izone = NULL;
248296465Sdelphij    ASN1_OCTET_STRING *oct;
249296465Sdelphij    if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
250296465Sdelphij        X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE);
251296465Sdelphij        M_ASN1_INTEGER_free(izone);
252296465Sdelphij        return NULL;
253296465Sdelphij    }
254296465Sdelphij    oct = SXNET_get_id_INTEGER(sx, izone);
255296465Sdelphij    M_ASN1_INTEGER_free(izone);
256296465Sdelphij    return oct;
25755714Skris}
25855714Skris
25955714SkrisASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
26055714Skris{
261296465Sdelphij    SXNETID *id;
262296465Sdelphij    int i;
263296465Sdelphij    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
264296465Sdelphij        id = sk_SXNETID_value(sx->ids, i);
265296465Sdelphij        if (!M_ASN1_INTEGER_cmp(id->zone, zone))
266296465Sdelphij            return id->user;
267296465Sdelphij    }
268296465Sdelphij    return NULL;
26955714Skris}
27055714Skris
27155714SkrisIMPLEMENT_STACK_OF(SXNETID)
272296465Sdelphij
27355714SkrisIMPLEMENT_ASN1_SET_OF(SXNETID)
274