diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_lib.c | 103 |
1 files changed, 47 insertions, 56 deletions
diff --git a/src/lib/libcrypto/x509/x509_lib.c b/src/lib/libcrypto/x509/x509_lib.c index 4347875885..161e638427 100644 --- a/src/lib/libcrypto/x509/x509_lib.c +++ b/src/lib/libcrypto/x509/x509_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_lib.c,v 1.21 2024/05/28 15:40:38 tb Exp $ */ | 1 | /* $OpenBSD: x509_lib.c,v 1.22 2024/06/17 05:31:26 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 1999. | 3 | * project 1999. |
| 4 | */ | 4 | */ |
| @@ -178,69 +178,60 @@ X509V3_EXT_d2i(X509_EXTENSION *ext) | |||
| 178 | } | 178 | } |
| 179 | LCRYPTO_ALIAS(X509V3_EXT_d2i); | 179 | LCRYPTO_ALIAS(X509V3_EXT_d2i); |
| 180 | 180 | ||
| 181 | /* Get critical flag and decoded version of extension from a NID. | 181 | /* |
| 182 | * The "idx" variable returns the last found extension and can | 182 | * This API is only safe to call with known nid, crit != NULL and idx == NULL. |
| 183 | * be used to retrieve multiple extensions of the same NID. | 183 | * On NULL return, crit acts as a failure indicator: crit == -1 means an |
| 184 | * However multiple extensions with the same NID is usually | 184 | * extension of type nid was not present, crit != -1 is fatal: crit == -2 |
| 185 | * due to a badly encoded certificate so if idx is NULL we | 185 | * means multiple extensions of type nid are present; if crit is 0 or 1, this |
| 186 | * choke if multiple extensions exist. | 186 | * implies the extension was found but could not be decoded. |
| 187 | * The "crit" variable is set to the critical value. | ||
| 188 | * The return value is the decoded extension or NULL on | ||
| 189 | * error. The actual error can have several different causes, | ||
| 190 | * the value of *crit reflects the cause: | ||
| 191 | * >= 0, extension found but not decoded (reflects critical value). | ||
| 192 | * -1 extension not found. | ||
| 193 | * -2 extension occurs more than once. | ||
| 194 | */ | 187 | */ |
| 195 | 188 | ||
| 196 | void * | 189 | void * |
| 197 | X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx) | 190 | X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx) |
| 198 | { | 191 | { |
| 199 | int lastpos, i; | 192 | X509_EXTENSION *ext; |
| 200 | X509_EXTENSION *ex, *found_ex = NULL; | 193 | int lastpos = idx == NULL ? -1 : *idx; |
| 201 | 194 | ||
| 202 | if (!x) { | 195 | if (crit != NULL) |
| 203 | if (idx) | 196 | *crit = -1; |
| 204 | *idx = -1; | 197 | if (idx != NULL) |
| 205 | if (crit) | 198 | *idx = -1; |
| 206 | *crit = -1; | 199 | |
| 200 | /* | ||
| 201 | * Nothing to do if no extensions, unknown nid, or missing extension. | ||
| 202 | */ | ||
| 203 | |||
| 204 | if (x == NULL) | ||
| 205 | return NULL; | ||
| 206 | if ((lastpos = X509v3_get_ext_by_NID(x, nid, lastpos)) < 0) | ||
| 207 | return NULL; | ||
| 208 | if ((ext = X509v3_get_ext(x, lastpos)) == NULL) | ||
| 209 | return NULL; | ||
| 210 | |||
| 211 | /* | ||
| 212 | * API madness. Only check for a second extension of type nid if | ||
| 213 | * idx == NULL. Indicate this by setting *crit to -2. If idx != NULL, | ||
| 214 | * don't care and set *idx to the index of the first extension found. | ||
| 215 | */ | ||
| 216 | |||
| 217 | if (idx == NULL && X509v3_get_ext_by_NID(x, nid, lastpos) > 0) { | ||
| 218 | if (crit != NULL) | ||
| 219 | *crit = -2; | ||
| 207 | return NULL; | 220 | return NULL; |
| 208 | } | ||
| 209 | if (idx) | ||
| 210 | lastpos = *idx + 1; | ||
| 211 | else | ||
| 212 | lastpos = 0; | ||
| 213 | if (lastpos < 0) | ||
| 214 | lastpos = 0; | ||
| 215 | for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { | ||
| 216 | ex = sk_X509_EXTENSION_value(x, i); | ||
| 217 | if (OBJ_obj2nid(ex->object) == nid) { | ||
| 218 | if (idx) { | ||
| 219 | *idx = i; | ||
| 220 | found_ex = ex; | ||
| 221 | break; | ||
| 222 | } else if (found_ex) { | ||
| 223 | /* Found more than one */ | ||
| 224 | if (crit) | ||
| 225 | *crit = -2; | ||
| 226 | return NULL; | ||
| 227 | } | ||
| 228 | found_ex = ex; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | if (found_ex) { | ||
| 232 | /* Found it */ | ||
| 233 | if (crit) | ||
| 234 | *crit = X509_EXTENSION_get_critical(found_ex); | ||
| 235 | return X509V3_EXT_d2i(found_ex); | ||
| 236 | } | 221 | } |
| 237 | 222 | ||
| 238 | /* Extension not found */ | 223 | /* |
| 239 | if (idx) | 224 | * Another beautiful API detail: *crit will be set to 0 or 1, so if the |
| 240 | *idx = -1; | 225 | * extension fails to decode, we can deduce this from return value NULL |
| 241 | if (crit) | 226 | * and crit != -1. |
| 242 | *crit = -1; | 227 | */ |
| 243 | return NULL; | 228 | |
| 229 | if (crit != NULL) | ||
| 230 | *crit = X509_EXTENSION_get_critical(ext); | ||
| 231 | if (idx != NULL) | ||
| 232 | *idx = lastpos; | ||
| 233 | |||
| 234 | return X509V3_EXT_d2i(ext); | ||
| 244 | } | 235 | } |
| 245 | LCRYPTO_ALIAS(X509V3_get_d2i); | 236 | LCRYPTO_ALIAS(X509V3_get_d2i); |
| 246 | 237 | ||
