]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
fecb3aae | 2 | * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. |
9d6b1ce6 | 3 | * |
365a2d99 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
2039c421 RS |
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 | |
d02b48c6 RE |
8 | */ |
9 | ||
9d6b1ce6 | 10 | #include <stddef.h> |
f0e8ae72 | 11 | #include <openssl/x509.h> |
9d6b1ce6 DSH |
12 | #include <openssl/asn1.h> |
13 | #include <openssl/asn1t.h> | |
0b3a4ef2 MC |
14 | #include <openssl/err.h> |
15 | #include "crypto/asn1.h" | |
25f2138b | 16 | #include "crypto/evp.h" |
d02b48c6 | 17 | |
9d6b1ce6 | 18 | ASN1_SEQUENCE(X509_ALGOR) = { |
0f113f3e MC |
19 | ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), |
20 | ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) | |
d339187b | 21 | } ASN1_SEQUENCE_END(X509_ALGOR) |
d02b48c6 | 22 | |
0f113f3e MC |
23 | ASN1_ITEM_TEMPLATE(X509_ALGORS) = |
24 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) | |
8931b30d DSH |
25 | ASN1_ITEM_TEMPLATE_END(X509_ALGORS) |
26 | ||
9d6b1ce6 | 27 | IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) |
8931b30d | 28 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) |
1241126a | 29 | IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) |
448be743 DSH |
30 | |
31 | int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) | |
0f113f3e | 32 | { |
a0fda2cf | 33 | if (alg == NULL) |
0f113f3e | 34 | return 0; |
a0fda2cf | 35 | |
04bc3c12 DDO |
36 | if (ptype != V_ASN1_UNDEF && alg->parameter == NULL |
37 | && (alg->parameter = ASN1_TYPE_new()) == NULL) | |
38 | return 0; | |
a0fda2cf F |
39 | |
40 | ASN1_OBJECT_free(alg->algorithm); | |
41 | alg->algorithm = aobj; | |
42 | ||
9944df11 | 43 | if (ptype == V_ASN1_EOC) |
0f113f3e MC |
44 | return 1; |
45 | if (ptype == V_ASN1_UNDEF) { | |
2ace7450 RS |
46 | ASN1_TYPE_free(alg->parameter); |
47 | alg->parameter = NULL; | |
0f113f3e MC |
48 | } else |
49 | ASN1_TYPE_set(alg->parameter, ptype, pval); | |
50 | return 1; | |
51 | } | |
448be743 | 52 | |
9944df11 DDO |
53 | X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval) |
54 | { | |
55 | ASN1_OBJECT *algo = OBJ_nid2obj(nid); | |
56 | X509_ALGOR *alg = NULL; | |
57 | ||
58 | if (algo == NULL) | |
59 | return NULL; | |
60 | if ((alg = X509_ALGOR_new()) == NULL) | |
61 | goto err; | |
62 | if (X509_ALGOR_set0(alg, algo, ptype, pval)) | |
63 | return alg; | |
64 | alg->algorithm = NULL; /* precaution to prevent double free */ | |
65 | ||
66 | err: | |
67 | X509_ALGOR_free(alg); | |
04bc3c12 | 68 | /* ASN1_OBJECT_free(algo) is not needed due to OBJ_nid2obj() */ |
9944df11 DDO |
69 | return NULL; |
70 | } | |
71 | ||
ac4e2577 DSH |
72 | void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, |
73 | const void **ppval, const X509_ALGOR *algor) | |
0f113f3e MC |
74 | { |
75 | if (paobj) | |
76 | *paobj = algor->algorithm; | |
77 | if (pptype) { | |
78 | if (algor->parameter == NULL) { | |
79 | *pptype = V_ASN1_UNDEF; | |
80 | return; | |
81 | } else | |
82 | *pptype = algor->parameter->type; | |
83 | if (ppval) | |
84 | *ppval = algor->parameter->value.ptr; | |
85 | } | |
86 | } | |
448be743 | 87 | |
ce25c720 | 88 | /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ |
ce25c720 | 89 | void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) |
0f113f3e | 90 | { |
04bc3c12 DDO |
91 | int type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF |
92 | : V_ASN1_NULL; | |
ce25c720 | 93 | |
04bc3c12 | 94 | (void)X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), type, NULL); |
0f113f3e | 95 | } |
4c52816d DSH |
96 | |
97 | int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) | |
0f113f3e MC |
98 | { |
99 | int rv; | |
100 | rv = OBJ_cmp(a->algorithm, b->algorithm); | |
101 | if (rv) | |
102 | return rv; | |
103 | if (!a->parameter && !b->parameter) | |
104 | return 0; | |
105 | return ASN1_TYPE_cmp(a->parameter, b->parameter); | |
106 | } | |
c72e5934 DWG |
107 | |
108 | int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) | |
109 | { | |
110 | if (src == NULL || dest == NULL) | |
d05bfc12 | 111 | return 0; |
c72e5934 DWG |
112 | |
113 | if (dest->algorithm) | |
114 | ASN1_OBJECT_free(dest->algorithm); | |
115 | dest->algorithm = NULL; | |
116 | ||
117 | if (dest->parameter) | |
118 | ASN1_TYPE_free(dest->parameter); | |
119 | dest->parameter = NULL; | |
120 | ||
121 | if (src->algorithm) | |
122 | if ((dest->algorithm = OBJ_dup(src->algorithm)) == NULL) | |
d05bfc12 | 123 | return 0; |
c72e5934 | 124 | |
19b4e6f8 NA |
125 | if (src->parameter != NULL) { |
126 | dest->parameter = ASN1_TYPE_new(); | |
127 | if (dest->parameter == NULL) | |
128 | return 0; | |
129 | ||
c72e5934 DWG |
130 | /* Assuming this is also correct for a BOOL. |
131 | * set does copy as a side effect. | |
132 | */ | |
bb82ef11 P |
133 | if (ASN1_TYPE_set1(dest->parameter, src->parameter->type, |
134 | src->parameter->value.ptr) == 0) | |
d05bfc12 | 135 | return 0; |
19b4e6f8 | 136 | } |
c72e5934 DWG |
137 | |
138 | return 1; | |
139 | } | |
0b3a4ef2 MC |
140 | |
141 | /* allocate and set algorithm ID from EVP_MD, default SHA1 */ | |
adf7e6d1 | 142 | int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md) |
0b3a4ef2 | 143 | { |
04bc3c12 DDO |
144 | X509_ALGOR *alg; |
145 | ||
0b3a4ef2 MC |
146 | /* Default is SHA1 so no need to create it - still success */ |
147 | if (md == NULL || EVP_MD_is_a(md, "SHA1")) | |
148 | return 1; | |
04bc3c12 | 149 | if ((alg = X509_ALGOR_new()) == NULL) |
0b3a4ef2 | 150 | return 0; |
04bc3c12 DDO |
151 | X509_ALGOR_set_md(alg, md); |
152 | *palg = alg; | |
0b3a4ef2 MC |
153 | return 1; |
154 | } | |
155 | ||
156 | /* convert algorithm ID to EVP_MD, default SHA1 */ | |
adf7e6d1 | 157 | const EVP_MD *ossl_x509_algor_get_md(X509_ALGOR *alg) |
0b3a4ef2 MC |
158 | { |
159 | const EVP_MD *md; | |
160 | ||
161 | if (alg == NULL) | |
162 | return EVP_sha1(); | |
163 | md = EVP_get_digestbyobj(alg->algorithm); | |
164 | if (md == NULL) | |
9311d0c4 | 165 | ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_DIGEST); |
0b3a4ef2 MC |
166 | return md; |
167 | } | |
168 | ||
adf7e6d1 | 169 | X509_ALGOR *ossl_x509_algor_mgf1_decode(X509_ALGOR *alg) |
0b3a4ef2 MC |
170 | { |
171 | if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) | |
172 | return NULL; | |
173 | return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), | |
174 | alg->parameter); | |
175 | } | |
176 | ||
177 | /* Allocate and set MGF1 algorithm ID from EVP_MD */ | |
adf7e6d1 | 178 | int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) |
0b3a4ef2 MC |
179 | { |
180 | X509_ALGOR *algtmp = NULL; | |
181 | ASN1_STRING *stmp = NULL; | |
182 | ||
183 | *palg = NULL; | |
184 | if (mgf1md == NULL || EVP_MD_is_a(mgf1md, "SHA1")) | |
185 | return 1; | |
186 | /* need to embed algorithm ID inside another */ | |
adf7e6d1 | 187 | if (!ossl_x509_algor_new_from_md(&algtmp, mgf1md)) |
0b3a4ef2 MC |
188 | goto err; |
189 | if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) | |
190 | goto err; | |
9944df11 | 191 | *palg = ossl_X509_ALGOR_from_nid(NID_mgf1, V_ASN1_SEQUENCE, stmp); |
0b3a4ef2 MC |
192 | if (*palg == NULL) |
193 | goto err; | |
0b3a4ef2 MC |
194 | stmp = NULL; |
195 | err: | |
196 | ASN1_STRING_free(stmp); | |
197 | X509_ALGOR_free(algtmp); | |
9944df11 | 198 | return *palg != NULL; |
0b3a4ef2 | 199 | } |