/src/libressl/crypto/ct/ct_b64.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: ct_b64.c,v 1.6 2021/12/20 17:19:19 jsing Exp $ */ |
2 | | /* |
3 | | * Written by Rob Stradling (rob@comodo.com) and Stephen Henson |
4 | | * (steve@openssl.org) for the OpenSSL project 2014. |
5 | | */ |
6 | | /* ==================================================================== |
7 | | * Copyright (c) 2014 The OpenSSL Project. All rights reserved. |
8 | | * |
9 | | * Redistribution and use in source and binary forms, with or without |
10 | | * modification, are permitted provided that the following conditions |
11 | | * are met: |
12 | | * |
13 | | * 1. Redistributions of source code must retain the above copyright |
14 | | * notice, this list of conditions and the following disclaimer. |
15 | | * |
16 | | * 2. Redistributions in binary form must reproduce the above copyright |
17 | | * notice, this list of conditions and the following disclaimer in |
18 | | * the documentation and/or other materials provided with the |
19 | | * distribution. |
20 | | * |
21 | | * 3. All advertising materials mentioning features or use of this |
22 | | * software must display the following acknowledgment: |
23 | | * "This product includes software developed by the OpenSSL Project |
24 | | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
25 | | * |
26 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
27 | | * endorse or promote products derived from this software without |
28 | | * prior written permission. For written permission, please contact |
29 | | * licensing@OpenSSL.org. |
30 | | * |
31 | | * 5. Products derived from this software may not be called "OpenSSL" |
32 | | * nor may "OpenSSL" appear in their names without prior written |
33 | | * permission of the OpenSSL Project. |
34 | | * |
35 | | * 6. Redistributions of any form whatsoever must retain the following |
36 | | * acknowledgment: |
37 | | * "This product includes software developed by the OpenSSL Project |
38 | | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
39 | | * |
40 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
41 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
42 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
43 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
44 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
45 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
46 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
47 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
48 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
49 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
50 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
51 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
52 | | * ==================================================================== |
53 | | * |
54 | | * This product includes cryptographic software written by Eric Young |
55 | | * (eay@cryptsoft.com). This product includes software written by Tim |
56 | | * Hudson (tjh@cryptsoft.com). |
57 | | * |
58 | | */ |
59 | | |
60 | | #include <limits.h> |
61 | | #include <string.h> |
62 | | |
63 | | #include <openssl/ct.h> |
64 | | #include <openssl/err.h> |
65 | | #include <openssl/evp.h> |
66 | | |
67 | | #include "bytestring.h" |
68 | | #include "ct_local.h" |
69 | | |
70 | | /* |
71 | | * Decodes the base64 string |in| into |out|. |
72 | | * A new string will be malloc'd and assigned to |out|. This will be owned by |
73 | | * the caller. Do not provide a pre-allocated string in |out|. |
74 | | */ |
75 | | static int |
76 | | ct_base64_decode(const char *in, unsigned char **out) |
77 | 0 | { |
78 | 0 | size_t inlen = strlen(in); |
79 | 0 | int outlen, i; |
80 | 0 | unsigned char *outbuf = NULL; |
81 | |
|
82 | 0 | if (inlen == 0) { |
83 | 0 | *out = NULL; |
84 | 0 | return 0; |
85 | 0 | } |
86 | | |
87 | 0 | outlen = (inlen / 4) * 3; |
88 | 0 | outbuf = malloc(outlen); |
89 | 0 | if (outbuf == NULL) { |
90 | 0 | CTerror(ERR_R_MALLOC_FAILURE); |
91 | 0 | goto err; |
92 | 0 | } |
93 | | |
94 | 0 | outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen); |
95 | 0 | if (outlen < 0) { |
96 | 0 | CTerror(CT_R_BASE64_DECODE_ERROR); |
97 | 0 | goto err; |
98 | 0 | } |
99 | | |
100 | | /* |
101 | | * Subtract padding bytes from |outlen|. |
102 | | * Any more than 2 is malformed. |
103 | | */ |
104 | 0 | i = 0; |
105 | 0 | while (in[--inlen] == '=') { |
106 | 0 | --outlen; |
107 | 0 | if (++i > 2) |
108 | 0 | goto err; |
109 | 0 | } |
110 | | |
111 | 0 | *out = outbuf; |
112 | 0 | return outlen; |
113 | 0 | err: |
114 | 0 | free(outbuf); |
115 | 0 | return -1; |
116 | 0 | } |
117 | | |
118 | | SCT * |
119 | | SCT_new_from_base64(unsigned char version, const char *logid_base64, |
120 | | ct_log_entry_type_t entry_type, uint64_t timestamp, |
121 | | const char *extensions_base64, const char *signature_base64) |
122 | 0 | { |
123 | 0 | unsigned char *dec = NULL; |
124 | 0 | int declen; |
125 | 0 | SCT *sct; |
126 | 0 | CBS cbs; |
127 | |
|
128 | 0 | if ((sct = SCT_new()) == NULL) { |
129 | 0 | CTerror(ERR_R_MALLOC_FAILURE); |
130 | 0 | return NULL; |
131 | 0 | } |
132 | | |
133 | | /* |
134 | | * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we |
135 | | * can only construct SCT versions that have been defined. |
136 | | */ |
137 | 0 | if (!SCT_set_version(sct, version)) { |
138 | 0 | CTerror(CT_R_SCT_UNSUPPORTED_VERSION); |
139 | 0 | goto err; |
140 | 0 | } |
141 | | |
142 | 0 | declen = ct_base64_decode(logid_base64, &dec); |
143 | 0 | if (declen < 0) { |
144 | 0 | CTerror(X509_R_BASE64_DECODE_ERROR); |
145 | 0 | goto err; |
146 | 0 | } |
147 | 0 | if (!SCT_set0_log_id(sct, dec, declen)) |
148 | 0 | goto err; |
149 | 0 | dec = NULL; |
150 | |
|
151 | 0 | declen = ct_base64_decode(extensions_base64, &dec); |
152 | 0 | if (declen < 0) { |
153 | 0 | CTerror(X509_R_BASE64_DECODE_ERROR); |
154 | 0 | goto err; |
155 | 0 | } |
156 | 0 | SCT_set0_extensions(sct, dec, declen); |
157 | 0 | dec = NULL; |
158 | |
|
159 | 0 | declen = ct_base64_decode(signature_base64, &dec); |
160 | 0 | if (declen < 0) { |
161 | 0 | CTerror(X509_R_BASE64_DECODE_ERROR); |
162 | 0 | goto err; |
163 | 0 | } |
164 | | |
165 | 0 | CBS_init(&cbs, dec, declen); |
166 | 0 | if (!o2i_SCT_signature(sct, &cbs)) |
167 | 0 | goto err; |
168 | 0 | free(dec); |
169 | 0 | dec = NULL; |
170 | |
|
171 | 0 | SCT_set_timestamp(sct, timestamp); |
172 | |
|
173 | 0 | if (!SCT_set_log_entry_type(sct, entry_type)) |
174 | 0 | goto err; |
175 | | |
176 | 0 | return sct; |
177 | | |
178 | 0 | err: |
179 | 0 | free(dec); |
180 | 0 | SCT_free(sct); |
181 | 0 | return NULL; |
182 | 0 | } |
183 | | |
184 | | /* |
185 | | * Allocate, build and returns a new |ct_log| from input |pkey_base64| |
186 | | * It returns 1 on success, |
187 | | * 0 on decoding failure, or invalid parameter if any |
188 | | * -1 on internal (malloc) failure |
189 | | */ |
190 | | int |
191 | | CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name) |
192 | 0 | { |
193 | 0 | unsigned char *pkey_der = NULL; |
194 | 0 | int pkey_der_len; |
195 | 0 | const unsigned char *p; |
196 | 0 | EVP_PKEY *pkey = NULL; |
197 | |
|
198 | 0 | if (ct_log == NULL) { |
199 | 0 | CTerror(ERR_R_PASSED_NULL_PARAMETER); |
200 | 0 | return 0; |
201 | 0 | } |
202 | | |
203 | 0 | pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der); |
204 | 0 | if (pkey_der_len < 0) { |
205 | 0 | CTerror(CT_R_LOG_CONF_INVALID_KEY); |
206 | 0 | return 0; |
207 | 0 | } |
208 | | |
209 | 0 | p = pkey_der; |
210 | 0 | pkey = d2i_PUBKEY(NULL, &p, pkey_der_len); |
211 | 0 | free(pkey_der); |
212 | 0 | if (pkey == NULL) { |
213 | 0 | CTerror(CT_R_LOG_CONF_INVALID_KEY); |
214 | 0 | return 0; |
215 | 0 | } |
216 | | |
217 | 0 | *ct_log = CTLOG_new(pkey, name); |
218 | 0 | if (*ct_log == NULL) { |
219 | 0 | EVP_PKEY_free(pkey); |
220 | 0 | return 0; |
221 | 0 | } |
222 | | |
223 | 0 | return 1; |
224 | 0 | } |