Convert CRYPTO_LOCK_X509_* to new multi-threading API
[openssl.git] / crypto / x509v3 / v3_tlsf.c
1 /*
2  * Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2015.
3  */
4 /* ====================================================================
5  * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #include <stdio.h>
59 #include "internal/cryptlib.h"
60 #include "internal/o_str.h"
61 #include <openssl/asn1t.h>
62 #include <openssl/conf.h>
63 #include <openssl/x509v3.h>
64 #include "ext_dat.h"
65
66 static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method,
67                                              TLS_FEATURE *tls_feature,
68                                              STACK_OF(CONF_VALUE) *ext_list);
69 static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method,
70                                     X509V3_CTX *ctx,
71                                     STACK_OF(CONF_VALUE) *nval);
72
73 ASN1_ITEM_TEMPLATE(TLS_FEATURE) =
74         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TLS_FEATURE, ASN1_INTEGER)
75 static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE)
76
77 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE)
78
79 const X509V3_EXT_METHOD v3_tls_feature = {
80     NID_tlsfeature, 0,
81     ASN1_ITEM_ref(TLS_FEATURE),
82     0, 0, 0, 0,
83     0, 0,
84     (X509V3_EXT_I2V)i2v_TLS_FEATURE,
85     (X509V3_EXT_V2I)v2i_TLS_FEATURE,
86     0, 0,
87     NULL
88 };
89
90
91 typedef struct {
92     long num;
93     const char *name;
94 } TLS_FEATURE_NAME;
95
96 static TLS_FEATURE_NAME tls_feature_tbl[] = {
97     { 5, "status_request" },
98     { 17, "status_request_v2" }
99 };
100
101 /*
102  * i2v_TLS_FEATURE converts the TLS_FEATURE structure tls_feature into the
103  * STACK_OF(CONF_VALUE) structure ext_list. STACK_OF(CONF_VALUE) is the format
104  * used by the CONF library to represent a multi-valued extension.  ext_list is
105  * returned.
106  */
107 static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method,
108                                              TLS_FEATURE *tls_feature,
109                                              STACK_OF(CONF_VALUE) *ext_list)
110 {
111     int i;
112     size_t j;
113     ASN1_INTEGER *ai;
114     long tlsextid;
115     for (i = 0; i < sk_ASN1_INTEGER_num(tls_feature); i++) {
116         ai = sk_ASN1_INTEGER_value(tls_feature, i);
117         tlsextid = ASN1_INTEGER_get(ai);
118         for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++)
119             if (tlsextid == tls_feature_tbl[j].num)
120                 break;
121         if (j < OSSL_NELEM(tls_feature_tbl))
122             X509V3_add_value(NULL, tls_feature_tbl[j].name, &ext_list);
123         else
124             X509V3_add_value_int(NULL, ai, &ext_list);
125     }
126     return ext_list;
127 }
128
129 /*
130  * v2i_TLS_FEATURE converts the multi-valued extension nval into a TLS_FEATURE
131  * structure, which is returned if the conversion is successful.  In case of
132  * error, NULL is returned.
133  */
134 static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method,
135                                     X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
136 {
137     TLS_FEATURE *tlsf;
138     char *extval, *endptr;
139     ASN1_INTEGER *ai;
140     CONF_VALUE *val;
141     int i;
142     size_t j;
143     long tlsextid;
144
145     if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) {
146         X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE);
147         return NULL;
148     }
149
150     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
151         val = sk_CONF_VALUE_value(nval, i);
152         if (val->value)
153             extval = val->value;
154         else
155             extval = val->name;
156
157         for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++)
158             if (OPENSSL_strcasecmp(extval, tls_feature_tbl[j].name) == 0)
159                 break;
160         if (j < OSSL_NELEM(tls_feature_tbl))
161             tlsextid = tls_feature_tbl[j].num;
162         else {
163             tlsextid = strtol(extval, &endptr, 10);
164             if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) ||
165                 (tlsextid > 65535)) {
166                 X509V3err(X509V3_F_V2I_TLS_FEATURE, X509V3_R_INVALID_SYNTAX);
167                 X509V3_conf_err(val);
168                 goto err;
169             }
170         }
171
172         ai = ASN1_INTEGER_new();
173         if (ai == NULL) {
174             X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE);
175             goto err;
176         }
177         ASN1_INTEGER_set(ai, tlsextid);
178         sk_ASN1_INTEGER_push(tlsf, ai);
179     }
180     return tlsf;
181
182  err:
183     sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free);
184     return NULL;
185 }