1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/safestack.h> 13 #include <openssl/asn1.h> 14 #include <openssl/objects.h> 15 #include <openssl/evp.h> 16 #include <openssl/x509.h> 17 #include <openssl/x509v3.h> 18 #include "x509_local.h" 19 20 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) 21 { 22 if (x == NULL) 23 return 0; 24 return sk_X509_EXTENSION_num(x); 25 } 26 27 int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, 28 int lastpos) 29 { 30 ASN1_OBJECT *obj; 31 32 obj = OBJ_nid2obj(nid); 33 if (obj == NULL) 34 return -2; 35 return X509v3_get_ext_by_OBJ(x, obj, lastpos); 36 } 37 38 int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, 39 const ASN1_OBJECT *obj, int lastpos) 40 { 41 int n; 42 X509_EXTENSION *ex; 43 44 if (sk == NULL) 45 return -1; 46 lastpos++; 47 if (lastpos < 0) 48 lastpos = 0; 49 n = sk_X509_EXTENSION_num(sk); 50 for (; lastpos < n; lastpos++) { 51 ex = sk_X509_EXTENSION_value(sk, lastpos); 52 if (OBJ_cmp(ex->object, obj) == 0) 53 return lastpos; 54 } 55 return -1; 56 } 57 58 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, 59 int lastpos) 60 { 61 int n; 62 X509_EXTENSION *ex; 63 64 if (sk == NULL) 65 return -1; 66 lastpos++; 67 if (lastpos < 0) 68 lastpos = 0; 69 n = sk_X509_EXTENSION_num(sk); 70 for (; lastpos < n; lastpos++) { 71 ex = sk_X509_EXTENSION_value(sk, lastpos); 72 if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) 73 return lastpos; 74 } 75 return -1; 76 } 77 78 X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) 79 { 80 if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) 81 return NULL; 82 else 83 return sk_X509_EXTENSION_value(x, loc); 84 } 85 86 X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) 87 { 88 X509_EXTENSION *ret; 89 90 if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) 91 return NULL; 92 ret = sk_X509_EXTENSION_delete(x, loc); 93 return ret; 94 } 95 96 STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, 97 X509_EXTENSION *ex, int loc) 98 { 99 X509_EXTENSION *new_ex = NULL; 100 int n; 101 STACK_OF(X509_EXTENSION) *sk = NULL; 102 103 if (x == NULL) { 104 X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); 105 goto err2; 106 } 107 108 if (*x == NULL) { 109 if ((sk = sk_X509_EXTENSION_new_null()) == NULL) 110 goto err; 111 } else 112 sk = *x; 113 114 n = sk_X509_EXTENSION_num(sk); 115 if (loc > n) 116 loc = n; 117 else if (loc < 0) 118 loc = n; 119 120 if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) 121 goto err2; 122 if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) 123 goto err; 124 if (*x == NULL) 125 *x = sk; 126 return sk; 127 err: 128 X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); 129 err2: 130 X509_EXTENSION_free(new_ex); 131 if (x != NULL && *x == NULL) 132 sk_X509_EXTENSION_free(sk); 133 return NULL; 134 } 135 136 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, 137 int crit, 138 ASN1_OCTET_STRING *data) 139 { 140 ASN1_OBJECT *obj; 141 X509_EXTENSION *ret; 142 143 obj = OBJ_nid2obj(nid); 144 if (obj == NULL) { 145 X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); 146 return NULL; 147 } 148 ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); 149 if (ret == NULL) 150 ASN1_OBJECT_free(obj); 151 return ret; 152 } 153 154 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, 155 const ASN1_OBJECT *obj, int crit, 156 ASN1_OCTET_STRING *data) 157 { 158 X509_EXTENSION *ret; 159 160 if ((ex == NULL) || (*ex == NULL)) { 161 if ((ret = X509_EXTENSION_new()) == NULL) { 162 X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, 163 ERR_R_MALLOC_FAILURE); 164 return NULL; 165 } 166 } else 167 ret = *ex; 168 169 if (!X509_EXTENSION_set_object(ret, obj)) 170 goto err; 171 if (!X509_EXTENSION_set_critical(ret, crit)) 172 goto err; 173 if (!X509_EXTENSION_set_data(ret, data)) 174 goto err; 175 176 if ((ex != NULL) && (*ex == NULL)) 177 *ex = ret; 178 return ret; 179 err: 180 if ((ex == NULL) || (ret != *ex)) 181 X509_EXTENSION_free(ret); 182 return NULL; 183 } 184 185 int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) 186 { 187 if ((ex == NULL) || (obj == NULL)) 188 return 0; 189 ASN1_OBJECT_free(ex->object); 190 ex->object = OBJ_dup(obj); 191 return ex->object != NULL; 192 } 193 194 int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) 195 { 196 if (ex == NULL) 197 return 0; 198 ex->critical = (crit) ? 0xFF : -1; 199 return 1; 200 } 201 202 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) 203 { 204 int i; 205 206 if (ex == NULL) 207 return 0; 208 i = ASN1_OCTET_STRING_set(&ex->value, data->data, data->length); 209 if (!i) 210 return 0; 211 return 1; 212 } 213 214 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) 215 { 216 if (ex == NULL) 217 return NULL; 218 return ex->object; 219 } 220 221 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) 222 { 223 if (ex == NULL) 224 return NULL; 225 return &ex->value; 226 } 227 228 int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) 229 { 230 if (ex == NULL) 231 return 0; 232 if (ex->critical > 0) 233 return 1; 234 return 0; 235 } 236