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 66 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) 67 { 68 if (x == NULL) 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) return(-2); 79 return(X509v3_get_ext_by_OBJ(x,obj,lastpos)); 80 } 81 82 int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, const ASN1_OBJECT *obj, 83 int lastpos) 84 { 85 int n; 86 X509_EXTENSION *ex; 87 88 if (sk == NULL) return(-1); 89 lastpos++; 90 if (lastpos < 0) 91 lastpos=0; 92 n=sk_X509_EXTENSION_num(sk); 93 for ( ; lastpos < n; lastpos++) 94 { 95 ex=sk_X509_EXTENSION_value(sk,lastpos); 96 if (OBJ_cmp(ex->object,obj) == 0) 97 return(lastpos); 98 } 99 return(-1); 100 } 101 102 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, 103 int lastpos) 104 { 105 int n; 106 X509_EXTENSION *ex; 107 108 if (sk == NULL) return(-1); 109 lastpos++; 110 if (lastpos < 0) 111 lastpos=0; 112 n=sk_X509_EXTENSION_num(sk); 113 for ( ; lastpos < n; lastpos++) 114 { 115 ex=sk_X509_EXTENSION_value(sk,lastpos); 116 if ( ((ex->critical > 0) && crit) || 117 ((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 { 150 OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_PASSED_NULL_PARAMETER); 151 goto err2; 152 } 153 154 if (*x == NULL) 155 { 156 if ((sk=sk_X509_EXTENSION_new_null()) == NULL) 157 goto err; 158 } 159 else 160 sk= *x; 161 162 n=sk_X509_EXTENSION_num(sk); 163 if (loc > n) loc=n; 164 else if (loc < 0) loc=n; 165 166 if ((new_ex=X509_EXTENSION_dup(ex)) == NULL) 167 goto err2; 168 if (!sk_X509_EXTENSION_insert(sk,new_ex,loc)) 169 goto err; 170 if (*x == NULL) 171 *x=sk; 172 return(sk); 173 err: 174 OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_MALLOC_FAILURE); 175 err2: 176 if (new_ex != NULL) X509_EXTENSION_free(new_ex); 177 if (sk != NULL) sk_X509_EXTENSION_free(sk); 178 return(NULL); 179 } 180 181 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, 182 int crit, ASN1_OCTET_STRING *data) 183 { 184 const ASN1_OBJECT *obj; 185 X509_EXTENSION *ret; 186 187 obj=OBJ_nid2obj(nid); 188 if (obj == NULL) 189 { 190 OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_NID, X509_R_UNKNOWN_NID); 191 return(NULL); 192 } 193 ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data); 194 return(ret); 195 } 196 197 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, 198 const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data) 199 { 200 X509_EXTENSION *ret; 201 202 if ((ex == NULL) || (*ex == NULL)) 203 { 204 if ((ret=X509_EXTENSION_new()) == NULL) 205 { 206 OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_OBJ, ERR_R_MALLOC_FAILURE); 207 return(NULL); 208 } 209 } 210 else 211 ret= *ex; 212 213 if (!X509_EXTENSION_set_object(ret,obj)) 214 goto err; 215 if (!X509_EXTENSION_set_critical(ret,crit)) 216 goto err; 217 if (!X509_EXTENSION_set_data(ret,data)) 218 goto err; 219 220 if ((ex != NULL) && (*ex == NULL)) *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) return(0); 240 ex->critical=(crit)?0xFF:-1; 241 return(1); 242 } 243 244 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) 245 { 246 int i; 247 248 if (ex == NULL) return(0); 249 i=M_ASN1_OCTET_STRING_set(ex->value,data->data,data->length); 250 if (!i) return(0); 251 return(1); 252 } 253 254 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) 255 { 256 if (ex == NULL) return(NULL); 257 return(ex->object); 258 } 259 260 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) 261 { 262 if (ex == NULL) return(NULL); 263 return(ex->value); 264 } 265 266 int X509_EXTENSION_get_critical(X509_EXTENSION *ex) 267 { 268 if (ex == NULL) return(0); 269 if(ex->critical > 0) return 1; 270 return 0; 271 } 272