2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 dn_append(void *ctx
, const void *buf
, size_t len
)
36 VEC_ADDMANY(*(bvector
*)ctx
, buf
, len
);
40 certificate_to_trust_anchor_inner(br_x509_trust_anchor
*ta
,
41 br_x509_certificate
*xc
)
43 br_x509_decoder_context dc
;
44 bvector vdn
= VEC_INIT
;
47 br_x509_decoder_init(&dc
, dn_append
, &vdn
);
48 br_x509_decoder_push(&dc
, xc
->data
, xc
->data_len
);
49 pk
= br_x509_decoder_get_pkey(&dc
);
51 fprintf(stderr
, "ERROR: CA decoding failed with error %d\n",
52 br_x509_decoder_last_error(&dc
));
56 ta
->dn
.data
= VEC_TOARRAY(vdn
);
57 ta
->dn
.len
= VEC_LEN(vdn
);
60 if (br_x509_decoder_isCA(&dc
)) {
61 ta
->flags
|= BR_X509_TA_CA
;
63 switch (pk
->key_type
) {
65 ta
->pkey
.key_type
= BR_KEYTYPE_RSA
;
66 ta
->pkey
.key
.rsa
.n
= xblobdup(pk
->key
.rsa
.n
, pk
->key
.rsa
.nlen
);
67 ta
->pkey
.key
.rsa
.nlen
= pk
->key
.rsa
.nlen
;
68 ta
->pkey
.key
.rsa
.e
= xblobdup(pk
->key
.rsa
.e
, pk
->key
.rsa
.elen
);
69 ta
->pkey
.key
.rsa
.elen
= pk
->key
.rsa
.elen
;
72 ta
->pkey
.key_type
= BR_KEYTYPE_EC
;
73 ta
->pkey
.key
.ec
.curve
= pk
->key
.ec
.curve
;
74 ta
->pkey
.key
.ec
.q
= xblobdup(pk
->key
.ec
.q
, pk
->key
.ec
.qlen
);
75 ta
->pkey
.key
.ec
.qlen
= pk
->key
.ec
.qlen
;
78 fprintf(stderr
, "ERROR: unsupported public key type in CA\n");
86 br_x509_trust_anchor
*
87 certificate_to_trust_anchor(br_x509_certificate
*xc
)
89 br_x509_trust_anchor ta
;
91 if (certificate_to_trust_anchor_inner(&ta
, xc
) < 0) {
94 return xblobdup(&ta
, sizeof ta
);
100 free_ta_contents(br_x509_trust_anchor
*ta
)
103 switch (ta
->pkey
.key_type
) {
105 xfree(ta
->pkey
.key
.rsa
.n
);
106 xfree(ta
->pkey
.key
.rsa
.e
);
109 xfree(ta
->pkey
.key
.ec
.q
);
116 read_trust_anchors(anchor_list
*dst
, const char *fname
)
118 br_x509_certificate
*xcs
;
119 anchor_list tas
= VEC_INIT
;
122 xcs
= read_certificates(fname
, &num
);
126 for (u
= 0; u
< num
; u
++) {
127 br_x509_trust_anchor ta
;
129 if (certificate_to_trust_anchor_inner(&ta
, &xcs
[u
]) < 0) {
130 VEC_CLEAREXT(tas
, free_ta_contents
);
135 VEC_ADDMANY(*dst
, &VEC_ELT(tas
, 0), num
);
142 get_cert_signer_algo(br_x509_certificate
*xc
)
144 br_x509_decoder_context dc
;
147 br_x509_decoder_init(&dc
, 0, 0);
148 br_x509_decoder_push(&dc
, xc
->data
, xc
->data_len
);
149 err
= br_x509_decoder_last_error(&dc
);
152 "ERROR: certificate decoding failed with error %d\n",
156 return br_x509_decoder_get_signer_key_type(&dc
);
160 xwc_start_chain(const br_x509_class
**ctx
, const char *server_name
)
162 x509_noanchor_context
*xwc
;
164 xwc
= (x509_noanchor_context
*)ctx
;
165 (*xwc
->inner
)->start_chain(xwc
->inner
, server_name
);
169 xwc_start_cert(const br_x509_class
**ctx
, uint32_t length
)
171 x509_noanchor_context
*xwc
;
173 xwc
= (x509_noanchor_context
*)ctx
;
174 (*xwc
->inner
)->start_cert(xwc
->inner
, length
);
178 xwc_append(const br_x509_class
**ctx
, const unsigned char *buf
, size_t len
)
180 x509_noanchor_context
*xwc
;
182 xwc
= (x509_noanchor_context
*)ctx
;
183 (*xwc
->inner
)->append(xwc
->inner
, buf
, len
);
187 xwc_end_cert(const br_x509_class
**ctx
)
189 x509_noanchor_context
*xwc
;
191 xwc
= (x509_noanchor_context
*)ctx
;
192 (*xwc
->inner
)->end_cert(xwc
->inner
);
196 xwc_end_chain(const br_x509_class
**ctx
)
198 x509_noanchor_context
*xwc
;
201 xwc
= (x509_noanchor_context
*)ctx
;
202 r
= (*xwc
->inner
)->end_chain(xwc
->inner
);
203 if (r
== BR_ERR_X509_NOT_TRUSTED
) {
209 static const br_x509_pkey
*
210 xwc_get_pkey(const br_x509_class
*const *ctx
, unsigned *usages
)
212 x509_noanchor_context
*xwc
;
214 xwc
= (x509_noanchor_context
*)ctx
;
215 return (*xwc
->inner
)->get_pkey(xwc
->inner
, usages
);
219 const br_x509_class x509_noanchor_vtable
= {
220 sizeof(x509_noanchor_context
),
231 x509_noanchor_init(x509_noanchor_context
*xwc
, const br_x509_class
**inner
)
233 xwc
->vtable
= &x509_noanchor_vtable
;