1 /* 2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 <openssl/objects.h> 11 #include "obj_xref.h" 12 #include "internal/nelem.h" 13 #include <openssl/err.h> 14 15 static STACK_OF(nid_triple) *sig_app, *sigx_app; 16 17 static int sig_cmp(const nid_triple *a, const nid_triple *b) 18 { 19 return a->sign_id - b->sign_id; 20 } 21 22 DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); 23 IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); 24 25 static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b) 26 { 27 return (*a)->sign_id - (*b)->sign_id; 28 } 29 30 DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); 31 32 static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b) 33 { 34 int ret; 35 ret = (*a)->hash_id - (*b)->hash_id; 36 if (ret) 37 return ret; 38 return (*a)->pkey_id - (*b)->pkey_id; 39 } 40 41 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); 42 43 int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) 44 { 45 nid_triple tmp; 46 const nid_triple *rv = NULL; 47 tmp.sign_id = signid; 48 49 if (sig_app != NULL) { 50 int idx = sk_nid_triple_find(sig_app, &tmp); 51 rv = sk_nid_triple_value(sig_app, idx); 52 } 53 #ifndef OBJ_XREF_TEST2 54 if (rv == NULL) { 55 rv = OBJ_bsearch_sig(&tmp, sigoid_srt, OSSL_NELEM(sigoid_srt)); 56 } 57 #endif 58 if (rv == NULL) 59 return 0; 60 if (pdig_nid) 61 *pdig_nid = rv->hash_id; 62 if (ppkey_nid) 63 *ppkey_nid = rv->pkey_id; 64 return 1; 65 } 66 67 int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) 68 { 69 nid_triple tmp; 70 const nid_triple *t = &tmp; 71 const nid_triple **rv = NULL; 72 73 tmp.hash_id = dig_nid; 74 tmp.pkey_id = pkey_nid; 75 76 if (sigx_app) { 77 int idx = sk_nid_triple_find(sigx_app, &tmp); 78 if (idx >= 0) { 79 t = sk_nid_triple_value(sigx_app, idx); 80 rv = &t; 81 } 82 } 83 #ifndef OBJ_XREF_TEST2 84 if (rv == NULL) { 85 rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, OSSL_NELEM(sigoid_srt_xref)); 86 } 87 #endif 88 if (rv == NULL) 89 return 0; 90 if (psignid) 91 *psignid = (*rv)->sign_id; 92 return 1; 93 } 94 95 int OBJ_add_sigid(int signid, int dig_id, int pkey_id) 96 { 97 nid_triple *ntr; 98 if (sig_app == NULL) 99 sig_app = sk_nid_triple_new(sig_sk_cmp); 100 if (sig_app == NULL) 101 return 0; 102 if (sigx_app == NULL) 103 sigx_app = sk_nid_triple_new(sigx_cmp); 104 if (sigx_app == NULL) 105 return 0; 106 if ((ntr = OPENSSL_malloc(sizeof(*ntr))) == NULL) { 107 ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE); 108 return 0; 109 } 110 ntr->sign_id = signid; 111 ntr->hash_id = dig_id; 112 ntr->pkey_id = pkey_id; 113 114 if (!sk_nid_triple_push(sig_app, ntr)) { 115 OPENSSL_free(ntr); 116 return 0; 117 } 118 119 if (!sk_nid_triple_push(sigx_app, ntr)) 120 return 0; 121 122 sk_nid_triple_sort(sig_app); 123 sk_nid_triple_sort(sigx_app); 124 125 return 1; 126 } 127 128 static void sid_free(nid_triple *tt) 129 { 130 OPENSSL_free(tt); 131 } 132 133 void OBJ_sigid_free(void) 134 { 135 sk_nid_triple_pop_free(sig_app, sid_free); 136 sig_app = NULL; 137 sk_nid_triple_free(sigx_app); 138 sigx_app = NULL; 139 } 140