Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions
8 : : * are met:
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer
11 : : * in this position and unchanged.
12 : : * 2. Redistributions in binary form must reproduce the above copyright
13 : : * notice, this list of conditions and the following disclaimer in the
14 : : * documentation and/or other materials provided with the distribution.
15 : : *
16 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : #include <sys/stat.h>
29 : : #include <sys/param.h>
30 : :
31 : : #include <fcntl.h>
32 : :
33 : : #include <openssl/err.h>
34 : : #include <openssl/ssl.h>
35 : :
36 : : #include "pkg.h"
37 : : #include "private/event.h"
38 : : #include "private/pkg.h"
39 : : #include "private/pkgsign.h"
40 : :
41 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
42 : : /*
43 : : * This matches the historical usage for pkg. Older versions sign the hex
44 : : * encoding of the SHA256 checksum. If we ever deprecated RSA, this can go
45 : : * away.
46 : : */
47 : : static EVP_MD *md_pkg_sha1;
48 : :
49 : : static EVP_MD *
50 : 0 : EVP_md_pkg_sha1(void)
51 : : {
52 : :
53 [ # # ]: 0 : if (md_pkg_sha1 != NULL)
54 : 0 : return (md_pkg_sha1);
55 : :
56 : 0 : md_pkg_sha1 = EVP_MD_meth_dup(EVP_sha1());
57 [ # # ]: 0 : if (md_pkg_sha1 == NULL)
58 : 0 : return (NULL);
59 : :
60 : 0 : EVP_MD_meth_set_result_size(md_pkg_sha1,
61 : 0 : pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX));
62 : 0 : return (md_pkg_sha1);
63 : 0 : }
64 : : #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
65 : :
66 : : struct ossl_sign_ctx {
67 : : struct pkgsign_ctx sctx;
68 : : EVP_PKEY *key;
69 : : };
70 : :
71 : : /* Grab the ossl context from a pkgsign_ctx. */
72 : : #define OSSL_CTX(c) ((struct ossl_sign_ctx *)(c))
73 : :
74 : : static int
75 : 4 : _load_private_key(struct ossl_sign_ctx *keyinfo)
76 : : {
77 : : FILE *fp;
78 : :
79 [ + - ]: 4 : if ((fp = fopen(keyinfo->sctx.path, "re")) == NULL)
80 : 0 : return (EPKG_FATAL);
81 : :
82 : 8 : keyinfo->key = PEM_read_PrivateKey(fp, 0, keyinfo->sctx.pw_cb,
83 : 4 : keyinfo->sctx.path);
84 [ + - ]: 4 : if (keyinfo->key == NULL) {
85 : 0 : fclose(fp);
86 : 0 : return (EPKG_FATAL);
87 : : }
88 : :
89 : 4 : fclose(fp);
90 : 4 : return (EPKG_OK);
91 : 4 : }
92 : :
93 : : static EVP_PKEY *
94 : 0 : _load_public_key_buf(unsigned char *cert, int certlen)
95 : : {
96 : : EVP_PKEY *pkey;
97 : : BIO *bp;
98 : : char errbuf[1024];
99 : :
100 : 0 : bp = BIO_new_mem_buf((void *)cert, certlen);
101 [ # # ]: 0 : if (bp == NULL) {
102 : 0 : pkg_emit_error("error allocating public key bio: %s",
103 : 0 : ERR_error_string(ERR_get_error(), errbuf));
104 : 0 : return (NULL);
105 : : }
106 : :
107 : 0 : pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
108 [ # # ]: 0 : if (pkey == NULL) {
109 : 0 : pkg_emit_error("error reading public key: %s",
110 : 0 : ERR_error_string(ERR_get_error(), errbuf));
111 : 0 : BIO_free(bp);
112 : 0 : return (NULL);
113 : : }
114 : :
115 : 0 : BIO_free(bp);
116 : 0 : return (pkey);
117 : 0 : }
118 : :
119 : : struct ossl_verify_cbdata {
120 : : unsigned char *key;
121 : : size_t keylen;
122 : : unsigned char *sig;
123 : : size_t siglen;
124 : : bool verbose;
125 : : };
126 : :
127 : : static int
128 : 0 : ossl_verify_cert_cb(int fd, void *ud)
129 : : {
130 : 0 : struct ossl_verify_cbdata *cbdata = ud;
131 : : char *sha256;
132 : : char *hash;
133 : : char errbuf[1024];
134 : 0 : EVP_PKEY *pkey = NULL;
135 : : EVP_PKEY_CTX *ctx;
136 : : int ret;
137 : :
138 : 0 : sha256 = pkg_checksum_fd(fd, PKG_HASH_TYPE_SHA256_HEX);
139 [ # # ]: 0 : if (sha256 == NULL)
140 : 0 : return (EPKG_FATAL);
141 : :
142 : 0 : hash = pkg_checksum_data(sha256, strlen(sha256),
143 : : PKG_HASH_TYPE_SHA256_RAW);
144 : 0 : free(sha256);
145 : :
146 : 0 : pkey = _load_public_key_buf(cbdata->key, cbdata->keylen);
147 [ # # ]: 0 : if (pkey == NULL) {
148 : 0 : free(hash);
149 : 0 : return (EPKG_FATAL);
150 : : }
151 : :
152 [ # # ]: 0 : if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
153 : 0 : EVP_PKEY_free(pkey);
154 : 0 : free(hash);
155 : 0 : return (EPKG_FATAL);
156 : : }
157 : :
158 : 0 : ctx = EVP_PKEY_CTX_new(pkey, NULL);
159 [ # # ]: 0 : if (ctx == NULL) {
160 : 0 : EVP_PKEY_free(pkey);
161 : 0 : free(hash);
162 : 0 : return (EPKG_FATAL);
163 : : }
164 : :
165 [ # # ]: 0 : if (EVP_PKEY_verify_init(ctx) <= 0) {
166 : 0 : EVP_PKEY_CTX_free(ctx);
167 : 0 : EVP_PKEY_free(pkey);
168 : 0 : free(hash);
169 : 0 : return (EPKG_FATAL);
170 : : }
171 : :
172 [ # # ]: 0 : if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
173 : 0 : EVP_PKEY_CTX_free(ctx);
174 : 0 : EVP_PKEY_free(pkey);
175 : 0 : free(hash);
176 : 0 : return (EPKG_FATAL);
177 : : }
178 : :
179 [ # # ]: 0 : if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) {
180 : 0 : EVP_PKEY_CTX_free(ctx);
181 : 0 : EVP_PKEY_free(pkey);
182 : 0 : free(hash);
183 : 0 : return (EPKG_FATAL);
184 : : }
185 : :
186 : 0 : ret = EVP_PKEY_verify(ctx, cbdata->sig, cbdata->siglen, hash,
187 : 0 : pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_RAW));
188 : 0 : free(hash);
189 [ # # # # ]: 0 : if (ret <= 0 && cbdata->verbose) {
190 [ # # ]: 0 : if (ret < 0)
191 : 0 : pkg_emit_error("rsa verify failed: %s",
192 : 0 : ERR_error_string(ERR_get_error(), errbuf));
193 : : else
194 : 0 : pkg_emit_error("rsa signature verification failure");
195 : 0 : }
196 [ # # ]: 0 : if (ret <= 0) {
197 : 0 : EVP_PKEY_CTX_free(ctx);
198 : 0 : EVP_PKEY_free(pkey);
199 : 0 : return (EPKG_FATAL);
200 : : }
201 : :
202 : 0 : EVP_PKEY_CTX_free(ctx);
203 : 0 : EVP_PKEY_free(pkey);
204 : :
205 : 0 : return (EPKG_OK);
206 : 0 : }
207 : :
208 : : static int
209 : 2 : ossl_verify_cert(const struct pkgsign_ctx *sctx __unused, unsigned char *key,
210 : : size_t keylen, unsigned char *sig, size_t siglen, int fd)
211 : : {
212 : : int ret;
213 : 2 : bool need_close = false;
214 : : struct ossl_verify_cbdata cbdata;
215 : :
216 : 2 : (void)lseek(fd, 0, SEEK_SET);
217 : :
218 : 2 : cbdata.key = key;
219 : 2 : cbdata.keylen = keylen;
220 : 2 : cbdata.sig = sig;
221 : 2 : cbdata.siglen = siglen;
222 : 2 : cbdata.verbose = true;
223 : :
224 : 2 : SSL_load_error_strings();
225 : 2 : OpenSSL_add_all_algorithms();
226 : 2 : OpenSSL_add_all_ciphers();
227 : :
228 : 2 : ret = pkg_emit_sandbox_call(ossl_verify_cert_cb, fd, &cbdata);
229 [ + - ]: 2 : if (need_close)
230 : 0 : close(fd);
231 : :
232 : 2 : return (ret);
233 : : }
234 : :
235 : : static int
236 : 0 : ossl_verify_cb(int fd, void *ud)
237 : : {
238 : 0 : struct ossl_verify_cbdata *cbdata = ud;
239 : : char *sha256;
240 : : char errbuf[1024];
241 : 0 : EVP_PKEY *pkey = NULL;
242 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
243 : : EVP_PKEY_CTX *ctx;
244 : : #else
245 : : RSA *rsa;
246 : : #endif
247 : : int ret;
248 : :
249 : 0 : sha256 = pkg_checksum_fd(fd, PKG_HASH_TYPE_SHA256_HEX);
250 [ # # ]: 0 : if (sha256 == NULL)
251 : 0 : return (EPKG_FATAL);
252 : :
253 : 0 : pkey = _load_public_key_buf(cbdata->key, cbdata->keylen);
254 [ # # ]: 0 : if (pkey == NULL) {
255 : 0 : free(sha256);
256 : 0 : return (EPKG_FATAL);
257 : : }
258 : :
259 [ # # ]: 0 : if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
260 : 0 : EVP_PKEY_free(pkey);
261 : 0 : free(sha256);
262 : 0 : return (EPKG_FATAL);
263 : : }
264 : :
265 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
266 : 0 : ctx = EVP_PKEY_CTX_new(pkey, NULL);
267 [ # # ]: 0 : if (ctx == NULL) {
268 : 0 : EVP_PKEY_free(pkey);
269 : 0 : free(sha256);
270 : 0 : return (EPKG_FATAL);
271 : : }
272 : :
273 [ # # ]: 0 : if (EVP_PKEY_verify_init(ctx) <= 0) {
274 : 0 : EVP_PKEY_CTX_free(ctx);
275 : 0 : EVP_PKEY_free(pkey);
276 : 0 : free(sha256);
277 : 0 : return (EPKG_FATAL);
278 : : }
279 : :
280 [ # # ]: 0 : if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
281 : 0 : EVP_PKEY_CTX_free(ctx);
282 : 0 : EVP_PKEY_free(pkey);
283 : 0 : free(sha256);
284 : 0 : return (EPKG_FATAL);
285 : : }
286 : :
287 [ # # ]: 0 : if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_md_pkg_sha1()) <= 0) {
288 : 0 : EVP_PKEY_CTX_free(ctx);
289 : 0 : EVP_PKEY_free(pkey);
290 : 0 : free(sha256);
291 : 0 : return (EPKG_FATAL);
292 : : }
293 : :
294 : 0 : ret = EVP_PKEY_verify(ctx, cbdata->sig, cbdata->siglen, sha256,
295 : 0 : pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX));
296 : : #else
297 : : rsa = EVP_PKEY_get1_RSA(pkey);
298 : :
299 : : ret = RSA_verify(NID_sha1, sha256,
300 : : pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX), cbdata->sig,
301 : : cbdata->siglen, rsa);
302 : : #endif
303 : 0 : free(sha256);
304 [ # # ]: 0 : if (ret <= 0) {
305 [ # # ]: 0 : if (ret < 0)
306 : 0 : pkg_emit_error("%s: %s", cbdata->key,
307 : 0 : ERR_error_string(ERR_get_error(), errbuf));
308 : : else
309 : 0 : pkg_emit_error("%s: rsa signature verification failure",
310 : 0 : cbdata->key);
311 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
312 : 0 : EVP_PKEY_CTX_free(ctx);
313 : : #else
314 : : RSA_free(rsa);
315 : : #endif
316 : 0 : EVP_PKEY_free(pkey);
317 : 0 : return (EPKG_FATAL);
318 : : }
319 : :
320 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
321 : 0 : EVP_PKEY_CTX_free(ctx);
322 : : #else
323 : : RSA_free(rsa);
324 : : #endif
325 : 0 : EVP_PKEY_free(pkey);
326 : :
327 : 0 : return (EPKG_OK);
328 : 0 : }
329 : :
330 : : static int
331 : 2 : ossl_verify(const struct pkgsign_ctx *sctx __unused, const char *keypath,
332 : : unsigned char *sig, size_t sig_len, int fd)
333 : : {
334 : : int ret;
335 : 2 : bool need_close = false;
336 : : struct ossl_verify_cbdata cbdata;
337 : : char *key_buf;
338 : : off_t key_len;
339 : :
340 [ - + ]: 2 : if (file_to_buffer(keypath, (char**)&key_buf, &key_len) != EPKG_OK) {
341 : 0 : pkg_emit_errno("ossl_verify", "cannot read key");
342 : 0 : return (EPKG_FATAL);
343 : : }
344 : :
345 : 2 : (void)lseek(fd, 0, SEEK_SET);
346 : :
347 : : /*
348 : : * XXX Older versions of pkg write out the NUL terminator of the
349 : : * signature, so we shim it out here to avoid breaking compatibility.
350 : : * We can't do it at a lower level in the caller, because other signers
351 : : * may use a binary format that could legitimately contain a nul byte.
352 : : */
353 [ - + ]: 2 : if (sig[sig_len - 1] == '\0')
354 : 2 : sig_len--;
355 : :
356 : 2 : cbdata.key = key_buf;
357 : 2 : cbdata.keylen = key_len;
358 : 2 : cbdata.sig = sig;
359 : 2 : cbdata.siglen = sig_len;
360 : 2 : cbdata.verbose = false;
361 : :
362 : 2 : SSL_load_error_strings();
363 : 2 : OpenSSL_add_all_algorithms();
364 : 2 : OpenSSL_add_all_ciphers();
365 : :
366 : 2 : ret = pkg_emit_sandbox_call(ossl_verify_cert_cb, fd, &cbdata);
367 [ + - ]: 2 : if (need_close)
368 : 0 : close(fd);
369 [ + - ]: 2 : if (ret != EPKG_OK) {
370 : 0 : cbdata.verbose = true;
371 : 0 : (void)lseek(fd, 0, SEEK_SET);
372 : 0 : ret = pkg_emit_sandbox_call(ossl_verify_cb, fd, &cbdata);
373 : 0 : }
374 : :
375 : 2 : free(key_buf);
376 : :
377 : 2 : return (ret);
378 : 2 : }
379 : :
380 : : int
381 : 5 : ossl_sign_data(struct pkgsign_ctx *sctx, const unsigned char *msg, size_t msgsz,
382 : : unsigned char **sigret, size_t *siglen)
383 : : {
384 : : char errbuf[1024];
385 : 5 : struct ossl_sign_ctx *keyinfo = OSSL_CTX(sctx);
386 : 5 : int max_len = 0, ret;
387 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
388 : : EVP_PKEY_CTX *ctx;
389 : : const EVP_MD *md;
390 : :
391 : : #if OPENSSL_VERSION_NUMBER < 0x30000000L
392 : : md = EVP_md_pkg_sha1();
393 : : #else
394 : 5 : md = EVP_sha256();
395 : : char *hash;
396 : : #endif
397 : : #else
398 : : RSA *rsa;
399 : : #endif
400 : :
401 [ + + + - ]: 5 : if (keyinfo->key == NULL && _load_private_key(keyinfo) != EPKG_OK) {
402 : 0 : pkg_emit_error("can't load key from %s", keyinfo->sctx.path);
403 : 0 : return (EPKG_FATAL);
404 : : }
405 : :
406 : 5 : max_len = EVP_PKEY_size(keyinfo->key);
407 : 5 : *sigret = xcalloc(1, max_len + 1);
408 : :
409 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
410 : 5 : ctx = EVP_PKEY_CTX_new(keyinfo->key, NULL);
411 [ + - ]: 5 : if (ctx == NULL)
412 : 0 : return (EPKG_FATAL);
413 : :
414 [ - + ]: 5 : if (EVP_PKEY_sign_init(ctx) <= 0) {
415 : 0 : EVP_PKEY_CTX_free(ctx);
416 : 0 : return (EPKG_FATAL);
417 : : }
418 : :
419 [ - + ]: 5 : if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) {
420 : 0 : EVP_PKEY_CTX_free(ctx);
421 : 0 : return (EPKG_FATAL);
422 : : }
423 : :
424 [ - + ]: 5 : if (EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) {
425 : 0 : EVP_PKEY_CTX_free(ctx);
426 : 0 : return (EPKG_FATAL);
427 : : }
428 : :
429 : 5 : *siglen = max_len;
430 : : #if OPENSSL_VERSION_NUMBER >= 0x30000000L
431 : 5 : hash = pkg_checksum_data(msg, msgsz, PKG_HASH_TYPE_SHA256_RAW);
432 : 10 : ret = EVP_PKEY_sign(ctx, *sigret, siglen, hash,
433 : 5 : EVP_MD_size(md));
434 : 5 : free(hash);
435 : : #else
436 : : ret = EVP_PKEY_sign(ctx, *sigret, siglen, msg, msgsz);
437 : : #endif
438 : :
439 : : #else /* OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER */
440 : : rsa = EVP_PKEY_get1_RSA(keyinfo->key);
441 : :
442 : : ret = RSA_sign(NID_sha1, msg, msgsz, *sigret, siglen, rsa);
443 : : #endif
444 [ - + ]: 5 : if (ret <= 0) {
445 : 0 : pkg_emit_error("%s: %s", keyinfo->sctx.path,
446 : 0 : ERR_error_string(ERR_get_error(), errbuf));
447 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
448 : 0 : EVP_PKEY_CTX_free(ctx);
449 : : #else
450 : : RSA_free(rsa);
451 : : #endif
452 : 0 : return (EPKG_FATAL);
453 : : }
454 : :
455 : : #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
456 [ + - ]: 5 : assert(*siglen < INT_MAX);
457 : 5 : EVP_PKEY_CTX_free(ctx);
458 : : #else
459 : : RSA_free(rsa);
460 : : #endif
461 : 5 : *siglen += 1;
462 : 5 : return (EPKG_OK);
463 : 5 : }
464 : :
465 : : int
466 : 4 : ossl_sign(struct pkgsign_ctx *sctx, const char *path, unsigned char **sigret,
467 : : size_t *siglen)
468 : : {
469 : 4 : struct ossl_sign_ctx *keyinfo = OSSL_CTX(sctx);
470 : : char *sha256;
471 : : int ret;
472 : :
473 [ + - ]: 4 : if (access(keyinfo->sctx.path, R_OK) == -1) {
474 : 0 : pkg_emit_errno("access", keyinfo->sctx.path);
475 : 0 : return (EPKG_FATAL);
476 : : }
477 : :
478 : 4 : sha256 = pkg_checksum_file(path, PKG_HASH_TYPE_SHA256_HEX);
479 [ + - ]: 4 : if (sha256 == NULL)
480 : 0 : return (EPKG_FATAL);
481 : :
482 : : #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
483 : 4 : ret = ossl_sign_data(sctx, sha256, strlen(sha256), sigret, siglen);
484 : : #else
485 : : ret = ossl_sign_data(sctx, sha256,
486 : : pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX), sigret, siglen);
487 : : #endif
488 : :
489 : 4 : free(sha256);
490 : :
491 : 4 : return (ret);
492 : 4 : }
493 : :
494 : : static int
495 : 7 : ossl_generate(struct pkgsign_ctx *sctx, const struct iovec *iov __unused,
496 : : int niov __unused)
497 : : {
498 : : char errbuf[1024];
499 : 7 : struct ossl_sign_ctx *keyinfo = OSSL_CTX(sctx);
500 : 7 : const char *path = sctx->path;
501 : : EVP_PKEY_CTX *ctx;
502 : : EVP_PKEY *pkey;
503 : : FILE *fp;
504 : : int rc;
505 : :
506 [ - + ]: 7 : if (niov != 0)
507 : 0 : return (EPKG_FATAL);
508 : :
509 : 7 : fp = fopen(path, "w");
510 [ + - ]: 7 : if (fp == NULL) {
511 : 0 : pkg_emit_errno("fopen write", path);
512 : 0 : return (EPKG_FATAL);
513 : : }
514 : :
515 [ - + ]: 7 : if (fchmod(fileno(fp), 0400) != 0) {
516 : 0 : pkg_emit_errno("fchmod", path);
517 : 0 : fclose(fp);
518 : 0 : return (EPKG_FATAL);
519 : : }
520 : :
521 : 7 : pkey = NULL;
522 : 7 : rc = EPKG_FATAL;
523 : 7 : ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
524 [ + - ]: 7 : if (ctx == NULL)
525 : 0 : goto out;
526 : :
527 [ - + ]: 7 : if (EVP_PKEY_keygen_init(ctx) <= 0)
528 : 0 : goto out;
529 : :
530 [ - + ]: 7 : if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0)
531 : 0 : goto out;
532 : :
533 [ - + ]: 7 : if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
534 : 0 : goto out;
535 : :
536 [ - + ]: 7 : if (PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, 0, NULL) <= 0)
537 : 0 : goto out;
538 : :
539 : 7 : rc = EPKG_OK;
540 [ + - ]: 7 : if (keyinfo->key != NULL)
541 : 0 : EVP_PKEY_free(keyinfo->key);
542 : 7 : keyinfo->key = pkey;
543 : : out:
544 [ + - ]: 7 : if (rc != EPKG_OK) {
545 : 0 : pkg_emit_error("%s: %s", path,
546 : 0 : ERR_error_string(ERR_get_error(), errbuf));
547 : :
548 : : /* keyinfo claims the pkey on success for any future operations. */
549 : 0 : EVP_PKEY_free(pkey);
550 : 0 : }
551 : :
552 : 7 : fclose(fp);
553 : 7 : EVP_PKEY_CTX_free(ctx);
554 : 7 : return (rc);
555 : 7 : }
556 : :
557 : : static int
558 : 8 : ossl_pubkey(struct pkgsign_ctx *sctx, char **pubkey, size_t *pubkeylen)
559 : : {
560 : : char errbuf[1024];
561 : 8 : struct ossl_sign_ctx *keyinfo = OSSL_CTX(sctx);
562 : : BIO *bp;
563 : :
564 [ + + + - ]: 8 : if (keyinfo->key == NULL && _load_private_key(keyinfo) != EPKG_OK) {
565 : 0 : pkg_emit_error("can't load key from %s", sctx->path);
566 : 0 : return (EPKG_FATAL);
567 : : }
568 : :
569 : 8 : bp = BIO_new(BIO_s_mem());
570 [ + - ]: 8 : if (bp == NULL) {
571 : 0 : pkg_emit_error("error allocating public key bio: %s",
572 : 0 : ERR_error_string(ERR_get_error(), errbuf));
573 : 0 : return (EPKG_FATAL);
574 : : }
575 : :
576 : 8 : BIO_set_close(bp, BIO_NOCLOSE);
577 : :
578 [ - + ]: 8 : if (PEM_write_bio_PUBKEY(bp, keyinfo->key) <= 0) {
579 : 0 : pkg_emit_error("error writing public key: %s",
580 : 0 : ERR_error_string(ERR_get_error(), errbuf));
581 : 0 : BIO_free(bp);
582 : 0 : return (EPKG_FATAL);
583 : : }
584 : :
585 : 8 : *pubkeylen = BIO_get_mem_data(bp, pubkey);
586 : 8 : BIO_free(bp);
587 : 8 : return (EPKG_OK);
588 : 8 : }
589 : :
590 : : static int
591 : 15 : ossl_new(const char *name __unused, struct pkgsign_ctx *sctx __unused)
592 : : {
593 : :
594 : 15 : SSL_load_error_strings();
595 : :
596 : 15 : OpenSSL_add_all_algorithms();
597 : 15 : OpenSSL_add_all_ciphers();
598 : :
599 : 15 : return (0);
600 : : }
601 : :
602 : : static void
603 : 11 : ossl_free(struct pkgsign_ctx *sctx)
604 : : {
605 : 11 : struct ossl_sign_ctx *keyinfo = OSSL_CTX(sctx);
606 : :
607 [ - + ]: 11 : if (keyinfo->key != NULL)
608 : 11 : EVP_PKEY_free(keyinfo->key);
609 : :
610 [ + - ]: 11 : ERR_free_strings();
611 : 11 : }
612 : :
613 : : const struct pkgsign_ops pkgsign_ossl = {
614 : : .pkgsign_ctx_size = sizeof(struct ossl_sign_ctx),
615 : : .pkgsign_new = ossl_new,
616 : : .pkgsign_free = ossl_free,
617 : :
618 : : .pkgsign_sign = ossl_sign,
619 : : .pkgsign_verify = ossl_verify,
620 : : .pkgsign_verify_cert = ossl_verify_cert,
621 : :
622 : : .pkgsign_generate = ossl_generate,
623 : : .pkgsign_pubkey = ossl_pubkey,
624 : : .pkgsign_sign_data = ossl_sign_data,
625 : : };
|