1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #include <openssl/asn1.h> 58 #include <openssl/err.h> 59 #include <openssl/evp.h> 60 #include <openssl/obj.h> 61 #include <openssl/stack.h> 62 #include <openssl/x509.h> 63 #include <openssl/x509v3.h> 64 65 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) 66 { 67 if (x == NULL) 68 return (0); 69 return (sk_X509_EXTENSION_num(x)); 70 } 71 72 int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, 73 int lastpos) 74 { 75 const ASN1_OBJECT *obj; 76 77 obj = OBJ_nid2obj(nid); 78 if (obj == NULL) 79 return (-2); 80 return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); 81 } 82 83 int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, 84 const ASN1_OBJECT *obj, int lastpos) 85 { 86 int n; 87 X509_EXTENSION *ex; 88 89 if (sk == NULL) 90 return (-1); 91 lastpos++; 92 if (lastpos < 0) 93 lastpos = 0; 94 n = sk_X509_EXTENSION_num(sk); 95 for (; lastpos < n; lastpos++) { 96 ex = sk_X509_EXTENSION_value(sk, lastpos); 97 if (OBJ_cmp(ex->object, obj) == 0) 98 return (lastpos); 99 } 100 return (-1); 101 } 102 103 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, 104 int lastpos) 105 { 106 int n; 107 X509_EXTENSION *ex; 108 109 if (sk == NULL) 110 return (-1); 111 lastpos++; 112 if (lastpos < 0) 113 lastpos = 0; 114 n = sk_X509_EXTENSION_num(sk); 115 for (; lastpos < n; lastpos++) { 116 ex = sk_X509_EXTENSION_value(sk, lastpos); 117 if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) 118 return (lastpos); 119 } 120 return (-1); 121 } 122 123 X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) 124 { 125 if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) 126 return NULL; 127 else 128 return sk_X509_EXTENSION_value(x, loc); 129 } 130 131 X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) 132 { 133 X509_EXTENSION *ret; 134 135 if (x == NULL || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) 136 return (NULL); 137 ret = sk_X509_EXTENSION_delete(x, loc); 138 return (ret); 139 } 140 141 STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, 142 X509_EXTENSION *ex, int loc) 143 { 144 X509_EXTENSION *new_ex = NULL; 145 int n; 146 STACK_OF(X509_EXTENSION) *sk = NULL; 147 148 if (x == NULL) { 149 OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); 150 goto err2; 151 } 152 153 if (*x == NULL) { 154 if ((sk = sk_X509_EXTENSION_new_null()) == NULL) 155 goto err; 156 } else 157 sk = *x; 158 159 n = sk_X509_EXTENSION_num(sk); 160 if (loc > n) 161 loc = n; 162 else if (loc < 0) 163 loc = n; 164 165 if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) 166 goto err2; 167 if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) 168 goto err; 169 if (*x == NULL) 170 *x = sk; 171 return (sk); 172 err: 173 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 174 err2: 175 if (new_ex != NULL) 176 X509_EXTENSION_free(new_ex); 177 if (sk != NULL) 178 sk_X509_EXTENSION_free(sk); 179 return (NULL); 180 } 181 182 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, 183 int crit, 184 ASN1_OCTET_STRING *data) 185 { 186 const ASN1_OBJECT *obj; 187 X509_EXTENSION *ret; 188 189 obj = OBJ_nid2obj(nid); 190 if (obj == NULL) { 191 OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); 192 return (NULL); 193 } 194 ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); 195 return (ret); 196 } 197 198 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, 199 const ASN1_OBJECT *obj, int crit, 200 ASN1_OCTET_STRING *data) 201 { 202 X509_EXTENSION *ret; 203 204 if ((ex == NULL) || (*ex == NULL)) { 205 if ((ret = X509_EXTENSION_new()) == NULL) { 206 OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); 207 return (NULL); 208 } 209 } else 210 ret = *ex; 211 212 if (!X509_EXTENSION_set_object(ret, obj)) 213 goto err; 214 if (!X509_EXTENSION_set_critical(ret, crit)) 215 goto err; 216 if (!X509_EXTENSION_set_data(ret, data)) 217 goto err; 218 219 if ((ex != NULL) && (*ex == NULL)) 220 *ex = ret; 221 return (ret); 222 err: 223 if ((ex == NULL) || (ret != *ex)) 224 X509_EXTENSION_free(ret); 225 return (NULL); 226 } 227 228 int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) 229 { 230 if ((ex == NULL) || (obj == NULL)) 231 return (0); 232 ASN1_OBJECT_free(ex->object); 233 ex->object = OBJ_dup(obj); 234 return ex->object != NULL; 235 } 236 237 int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) 238 { 239 if (ex == NULL) 240 return (0); 241 ex->critical = (crit) ? 0xFF : -1; 242 return (1); 243 } 244 245 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) 246 { 247 int i; 248 249 if (ex == NULL) 250 return (0); 251 i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length); 252 if (!i) 253 return (0); 254 return (1); 255 } 256 257 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) 258 { 259 if (ex == NULL) 260 return (NULL); 261 return (ex->object); 262 } 263 264 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) 265 { 266 if (ex == NULL) 267 return (NULL); 268 return (ex->value); 269 } 270 271 int X509_EXTENSION_get_critical(X509_EXTENSION *ex) 272 { 273 if (ex == NULL) 274 return (0); 275 if (ex->critical > 0) 276 return 1; 277 return 0; 278 } 279