155714Skris/* v3_sxnet.c */
2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
355714Skris * project 1999.
455714Skris */
555714Skris/* ====================================================================
655714Skris * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
755714Skris *
855714Skris * Redistribution and use in source and binary forms, with or without
955714Skris * modification, are permitted provided that the following conditions
1055714Skris * are met:
1155714Skris *
1255714Skris * 1. Redistributions of source code must retain the above copyright
1355714Skris *    notice, this list of conditions and the following disclaimer.
1455714Skris *
1555714Skris * 2. Redistributions in binary form must reproduce the above copyright
1655714Skris *    notice, this list of conditions and the following disclaimer in
1755714Skris *    the documentation and/or other materials provided with the
1855714Skris *    distribution.
1955714Skris *
2055714Skris * 3. All advertising materials mentioning features or use of this
2155714Skris *    software must display the following acknowledgment:
2255714Skris *    "This product includes software developed by the OpenSSL Project
2355714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2455714Skris *
2555714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2655714Skris *    endorse or promote products derived from this software without
2755714Skris *    prior written permission. For written permission, please contact
2855714Skris *    licensing@OpenSSL.org.
2955714Skris *
3055714Skris * 5. Products derived from this software may not be called "OpenSSL"
3155714Skris *    nor may "OpenSSL" appear in their names without prior written
3255714Skris *    permission of the OpenSSL Project.
3355714Skris *
3455714Skris * 6. Redistributions of any form whatsoever must retain the following
3555714Skris *    acknowledgment:
3655714Skris *    "This product includes software developed by the OpenSSL Project
3755714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3855714Skris *
3955714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4055714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4255714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4355714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4455714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4555714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4655714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4755714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4855714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4955714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5055714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5155714Skris * ====================================================================
5255714Skris *
5355714Skris * This product includes cryptographic software written by Eric Young
5455714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5555714Skris * Hudson (tjh@cryptsoft.com).
5655714Skris *
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/conf.h>
6255714Skris#include <openssl/asn1.h>
63109998Smarkm#include <openssl/asn1t.h>
6455714Skris#include <openssl/x509v3.h>
6555714Skris
6655714Skris/* Support for Thawte strong extranet extension */
6755714Skris
6855714Skris#define SXNET_TEST
6955714Skris
7055714Skrisstatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent);
7155714Skris#ifdef SXNET_TEST
7255714Skrisstatic SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
7355714Skris						STACK_OF(CONF_VALUE) *nval);
7455714Skris#endif
75167612Ssimonconst X509V3_EXT_METHOD v3_sxnet = {
76109998SmarkmNID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
77109998Smarkm0,0,0,0,
78109998Smarkm0,0,
79109998Smarkm0,
8055714Skris#ifdef SXNET_TEST
8155714Skris(X509V3_EXT_V2I)sxnet_v2i,
8255714Skris#else
83109998Smarkm0,
8455714Skris#endif
8555714Skris(X509V3_EXT_I2R)sxnet_i2r,
86109998Smarkm0,
8755714SkrisNULL
8855714Skris};
8955714Skris
90109998SmarkmASN1_SEQUENCE(SXNETID) = {
91109998Smarkm	ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
92109998Smarkm	ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
93109998Smarkm} ASN1_SEQUENCE_END(SXNETID)
9455714Skris
95109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(SXNETID)
9655714Skris
97109998SmarkmASN1_SEQUENCE(SXNET) = {
98109998Smarkm	ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
99109998Smarkm	ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
100109998Smarkm} ASN1_SEQUENCE_END(SXNET)
10155714Skris
102109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(SXNET)
10355714Skris
10455714Skrisstatic int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
10555714Skris	     int indent)
10655714Skris{
10755714Skris	long v;
10855714Skris	char *tmp;
10955714Skris	SXNETID *id;
11055714Skris	int i;
11155714Skris	v = ASN1_INTEGER_get(sx->version);
112160814Ssimon	BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
11355714Skris	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
11455714Skris		id = sk_SXNETID_value(sx->ids, i);
11555714Skris		tmp = i2s_ASN1_INTEGER(NULL, id->zone);
11655714Skris		BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
11768651Skris		OPENSSL_free(tmp);
11859191Skris		M_ASN1_OCTET_STRING_print(out, id->user);
11955714Skris	}
12055714Skris	return 1;
12155714Skris}
12255714Skris
12355714Skris#ifdef SXNET_TEST
12455714Skris
12555714Skris/* NBB: this is used for testing only. It should *not* be used for anything
12655714Skris * else because it will just take static IDs from the configuration file and
12755714Skris * they should really be separate values for each user.
12855714Skris */
12955714Skris
13055714Skris
13155714Skrisstatic SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
13255714Skris	     STACK_OF(CONF_VALUE) *nval)
13355714Skris{
13455714Skris	CONF_VALUE *cnf;
13555714Skris	SXNET *sx = NULL;
13655714Skris	int i;
13755714Skris	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
13855714Skris		cnf = sk_CONF_VALUE_value(nval, i);
13955714Skris		if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
14055714Skris								 return NULL;
14155714Skris	}
14255714Skris	return sx;
14355714Skris}
14455714Skris
14555714Skris
14655714Skris#endif
14755714Skris
14855714Skris/* Strong Extranet utility functions */
14955714Skris
15055714Skris/* Add an id given the zone as an ASCII number */
15155714Skris
15255714Skrisint SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
15355714Skris	     int userlen)
15455714Skris{
15555714Skris	ASN1_INTEGER *izone = NULL;
15655714Skris	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
157160814Ssimon		X509V3err(X509V3_F_SXNET_ADD_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
15855714Skris		return 0;
15955714Skris	}
16055714Skris	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,
16655714Skris	     int userlen)
16755714Skris{
16855714Skris	ASN1_INTEGER *izone = NULL;
16959191Skris	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
17055714Skris		X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE);
17159191Skris		M_ASN1_INTEGER_free(izone);
17255714Skris		return 0;
17355714Skris	}
17455714Skris	return SXNET_add_id_INTEGER(psx, izone, user, userlen);
17555714Skris
17655714Skris}
17755714Skris
17855714Skris/* Add an id given the zone as an ASN1_INTEGER.
17955714Skris * Note this version uses the passed integer and doesn't make a copy so don't
18055714Skris * free it up afterwards.
18155714Skris */
18255714Skris
18355714Skrisint SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
18455714Skris	     int userlen)
18555714Skris{
18655714Skris	SXNET *sx = NULL;
18755714Skris	SXNETID *id = NULL;
18855714Skris	if(!psx || !zone || !user) {
18955714Skris		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT);
19055714Skris		return 0;
19155714Skris	}
19255714Skris	if(userlen == -1) userlen = strlen(user);
19355714Skris	if(userlen > 64) {
19455714Skris		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG);
19555714Skris		return 0;
19655714Skris	}
19755714Skris	if(!*psx) {
19855714Skris		if(!(sx = SXNET_new())) goto err;
19955714Skris		if(!ASN1_INTEGER_set(sx->version, 0)) goto err;
20055714Skris		*psx = sx;
20155714Skris	} else sx = *psx;
20255714Skris	if(SXNET_get_id_INTEGER(sx, zone)) {
20355714Skris		X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID);
20455714Skris		return 0;
20555714Skris	}
20655714Skris
20755714Skris	if(!(id = SXNETID_new())) goto err;
20855714Skris	if(userlen == -1) userlen = strlen(user);
20955714Skris
21059191Skris	if(!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err;
21155714Skris	if(!sk_SXNETID_push(sx->ids, id)) goto err;
21255714Skris	id->zone = zone;
21355714Skris	return 1;
21455714Skris
21555714Skris	err:
21655714Skris	X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE);
21755714Skris	SXNETID_free(id);
21855714Skris	SXNET_free(sx);
21955714Skris	*psx = NULL;
22055714Skris	return 0;
22155714Skris}
22255714Skris
22355714SkrisASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
22455714Skris{
22555714Skris	ASN1_INTEGER *izone = NULL;
22655714Skris	ASN1_OCTET_STRING *oct;
22755714Skris	if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
22855714Skris		X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE);
22955714Skris		return NULL;
23055714Skris	}
23155714Skris	oct = SXNET_get_id_INTEGER(sx, izone);
23259191Skris	M_ASN1_INTEGER_free(izone);
23355714Skris	return oct;
23455714Skris}
23555714Skris
23655714SkrisASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
23755714Skris{
23855714Skris	ASN1_INTEGER *izone = NULL;
23955714Skris	ASN1_OCTET_STRING *oct;
24059191Skris	if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
24155714Skris		X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE);
24259191Skris		M_ASN1_INTEGER_free(izone);
24355714Skris		return NULL;
24455714Skris	}
24555714Skris	oct = SXNET_get_id_INTEGER(sx, izone);
24659191Skris	M_ASN1_INTEGER_free(izone);
24755714Skris	return oct;
24855714Skris}
24955714Skris
25055714SkrisASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
25155714Skris{
25255714Skris	SXNETID *id;
25355714Skris	int i;
25455714Skris	for(i = 0; i < sk_SXNETID_num(sx->ids); i++) {
25555714Skris		id = sk_SXNETID_value(sx->ids, i);
25659191Skris		if(!M_ASN1_INTEGER_cmp(id->zone, zone)) return id->user;
25755714Skris	}
25855714Skris	return NULL;
25955714Skris}
26055714Skris
26155714SkrisIMPLEMENT_STACK_OF(SXNETID)
26255714SkrisIMPLEMENT_ASN1_SET_OF(SXNETID)
263