1 /* $NetBSD: pkg_signature.c,v 1.9 2009/08/02 17:56:45 joerg Exp $ */
10 __RCSID("$NetBSD: pkg_signature.c,v 1.9 2009/08/02 17:56:45 joerg Exp $");
13 * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
14 * All rights reserved.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in
24 * the documentation and/or other materials provided with the
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
35 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 #include <nbcompat/sha2.h>
60 #include <nbcompat/unistd.h>
64 #include <archive_entry.h>
68 #define HASH_FNAME "+PKG_HASH"
69 #define SIGNATURE_FNAME "+PKG_SIGNATURE"
70 #define GPG_SIGNATURE_FNAME "+PKG_GPG_SIGNATURE"
72 struct signature_archive
{
73 struct archive
*archive
;
75 size_t sign_block_len
, sign_block_number
, sign_cur_block
;
77 unsigned char *sign_buf
;
81 hash_block(unsigned char *buf
, size_t buf_len
,
82 char hash
[SHA512_DIGEST_STRING_LENGTH
])
84 unsigned char digest
[SHA512_DIGEST_LENGTH
];
88 SHA512_Init(&hash_ctx
);
89 SHA512_Update(&hash_ctx
, buf
, buf_len
);
90 SHA512_Final(digest
, &hash_ctx
);
91 for (i
= 0; i
< SHA512_DIGEST_LENGTH
; ++i
) {
96 hash
[2 * i
] = '0' + c
;
98 hash
[2 * i
] = 'a' - 10 + c
;
102 hash
[2 * i
+ 1] = '0' + c
;
104 hash
[2 * i
+ 1] = 'a' - 10 + c
;
110 verify_signature_read_cb(struct archive
*archive
, void *cookie
, const void **buf
)
112 struct signature_archive
*state
= cookie
;
113 char hash
[SHA512_DIGEST_STRING_LENGTH
];
114 ssize_t len
, expected
;
116 if (state
->sign_cur_block
>= state
->sign_block_number
)
119 /* The following works for sign_block_len > 1 */
120 if (state
->sign_cur_block
+ 1 == state
->sign_block_number
)
121 expected
= state
->pkg_size
% state
->sign_block_len
;
123 expected
= state
->sign_block_len
;
125 len
= archive_read_data(state
->archive
, state
->sign_buf
, expected
);
126 if (len
!= expected
) {
127 warnx("Short read from package");
131 hash_block(state
->sign_buf
, len
, hash
);
133 if (strcmp(hash
, state
->sign_blocks
[state
->sign_cur_block
]) != 0) {
134 warnx("Invalid signature of block %llu",
135 (unsigned long long)state
->sign_cur_block
);
138 ++state
->sign_cur_block
;
139 *buf
= state
->sign_buf
;
144 free_signature_int(struct signature_archive
*state
)
148 if (state
->sign_blocks
!= NULL
) {
149 for (i
= 0; i
< state
->sign_block_number
; ++i
)
150 free(state
->sign_blocks
[i
]);
152 free(state
->sign_blocks
);
153 free(state
->sign_buf
);
158 verify_signature_close_cb(struct archive
*archive
, void *cookie
)
160 struct signature_archive
*state
= cookie
;
162 archive_read_finish(state
->archive
);
163 free_signature_int(state
);
168 read_file_from_archive(struct archive
*archive
, struct archive_entry
**entry
,
169 const char *fname
, char **content
, size_t *len
)
177 if (*entry
== NULL
&&
178 (r
= archive_read_next_header(archive
, entry
)) != ARCHIVE_OK
) {
179 if (r
== ARCHIVE_FATAL
) {
180 warnx("Cannot read from archive: %s",
181 archive_error_string(archive
));
183 warnx("Premature end of archive");
188 if (strcmp(archive_entry_pathname(*entry
), "//") == 0) {
189 archive_read_data_skip(archive
);
194 if (strcmp(fname
, archive_entry_pathname(*entry
)) != 0)
197 if (archive_entry_size(*entry
) > SSIZE_MAX
- 1) {
198 warnx("signature too large to process");
201 *len
= archive_entry_size(*entry
);
202 *content
= xmalloc(*len
+ 1);
204 if (archive_read_data(archive
, *content
, *len
) != (ssize_t
)*len
) {
205 warnx("cannot read complete %s from archive", fname
);
211 (*content
)[*len
] = '\0';
218 parse_hash_file(const char *hash_file
, char **pkgname
,
219 struct signature_archive
*state
)
221 static const char block1
[] = "pkgsrc signature\n\nversion: 1\npkgname: ";
222 static const char block2
[] = "algorithm: SHA512\nblock size: ";
223 static const char block3
[] = "file size: ";
224 static const char block4
[] = "end pkgsrc signature\n";
230 if (strncmp(hash_file
, block1
, strlen(block1
)) != 0)
232 hash_file
+= strlen(block1
);
234 len
= strcspn(hash_file
, "\n");
235 *pkgname
= xmalloc(len
+ 1);
236 memcpy(*pkgname
, hash_file
, len
);
237 (*pkgname
)[len
] = '\0';
238 for (i
= 0; i
< len
; ++i
) {
239 if (!isgraph((unsigned char)(*pkgname
)[i
]))
242 hash_file
+= len
+ 1;
244 if (strncmp(hash_file
, block2
, strlen(block2
)) != 0)
246 hash_file
+= strlen(block2
);
249 if (!isdigit((unsigned char)*hash_file
))
251 state
->sign_block_len
= strtoul(hash_file
, &next
, 10);
254 /* Assert sane minimum block size of 1KB */
255 if (*hash_file
++ != '\n' || errno
== ERANGE
|| state
->sign_block_len
< 1024)
258 if (strncmp(hash_file
, block3
, strlen(block3
)) != 0)
260 hash_file
+= strlen(block3
);
263 if (!isdigit((unsigned char)*hash_file
))
265 if (/* CONSTCOND */sizeof(off_t
) >= sizeof(long long))
266 state
->pkg_size
= strtoll(hash_file
, &next
, 10);
268 state
->pkg_size
= strtol(hash_file
, &next
, 10);
270 if (*hash_file
++ != '\n' || errno
== ERANGE
|| state
->pkg_size
< 1)
273 if (*hash_file
++ != '\n')
276 if (state
->pkg_size
/ state
->sign_block_len
> SSIZE_MAX
)
278 state
->sign_block_number
= (state
->pkg_size
+
279 state
->sign_block_len
- 1) / state
->sign_block_len
;
281 state
->sign_buf
= xmalloc(state
->sign_block_len
);
282 state
->sign_blocks
= xcalloc(state
->sign_block_number
, sizeof(char *));
284 for (i
= 0; i
< state
->sign_block_number
; ++i
) {
285 len
= strspn(hash_file
, "01234567889abcdef");
286 if (len
!= SHA512_DIGEST_LENGTH
* 2 || hash_file
[len
] != '\n')
288 state
->sign_blocks
[i
] = xmalloc(len
+ 1);
289 memcpy(state
->sign_blocks
[i
], hash_file
, len
);
290 state
->sign_blocks
[i
][len
] = '\0';
291 hash_file
+= len
+ 1;
294 if (strcmp(hash_file
, block4
) != 0)
300 for (i
= 0; i
< state
->sign_block_number
; ++i
)
301 free(state
->sign_blocks
[i
]);
302 free(state
->sign_blocks
);
303 state
->sign_blocks
= NULL
;
306 warnx("Unknown format of hash file");
313 pkg_verify_signature(struct archive
**archive
, struct archive_entry
**entry
,
316 struct signature_archive
*state
;
317 struct archive_entry
*my_entry
;
319 char *hash_file
, *signature_file
;
320 size_t hash_len
, signature_len
;
325 state
= xmalloc(sizeof(*state
));
326 state
->sign_blocks
= NULL
;
327 state
->sign_buf
= NULL
;
328 state
->archive
= NULL
;
330 r
= read_file_from_archive(*archive
, entry
, HASH_FNAME
,
331 &hash_file
, &hash_len
);
333 archive_read_finish(*archive
);
336 goto no_valid_signature
;
339 goto no_valid_signature
;
342 if (parse_hash_file(hash_file
, pkgname
, state
))
343 goto no_valid_signature
;
345 r
= read_file_from_archive(*archive
, entry
, SIGNATURE_FNAME
,
346 &signature_file
, &signature_len
);
348 archive_read_finish(*archive
);
352 goto no_valid_signature
;
355 r
= read_file_from_archive(*archive
, entry
,
357 &signature_file
, &signature_len
);
359 archive_read_finish(*archive
);
363 goto no_valid_signature
;
367 goto no_valid_signature
;
369 has_sig
= !detached_gpg_verify(hash_file
, hash_len
,
370 signature_file
, signature_len
, gpg_keyring_verify
);
372 free(signature_file
);
375 has_sig
= !easy_pkcs7_verify(hash_file
, hash_len
, signature_file
,
376 signature_len
, certs_packages
, 1);
378 free(signature_file
);
380 warnx("No OpenSSL support compiled in, skipping signature");
382 free(signature_file
);
386 r
= archive_read_next_header(*archive
, &my_entry
);
387 if (r
!= ARCHIVE_OK
) {
388 warnx("Cannot read inner package: %s",
389 archive_error_string(*archive
));
390 free_signature_int(state
);
391 goto no_valid_signature
;
394 if (archive_entry_size(my_entry
) != state
->pkg_size
) {
395 warnx("Package size doesn't match signature");
396 free_signature_int(state
);
397 goto no_valid_signature
;
400 state
->archive
= *archive
;
402 a
= archive_read_new();
403 archive_read_support_compression_all(a
);
404 archive_read_support_format_all(a
);
405 if (archive_read_open(a
, state
, NULL
, verify_signature_read_cb
,
406 verify_signature_close_cb
)) {
407 warnx("Can't open signed package file");
408 archive_read_finish(a
);
409 goto no_valid_signature
;
414 return has_sig
? 0 : -1;
421 pkg_full_signature_check(struct archive
**archive
)
423 struct archive_entry
*entry
= NULL
;
427 if (pkg_verify_signature(archive
, &entry
, &pkgname
))
432 /* XXX read PLIST and compare pkgname */
433 while ((r
= archive_read_next_header(*archive
, &entry
)) == ARCHIVE_OK
)
434 archive_read_data_skip(*archive
);
437 return r
== ARCHIVE_EOF
? 0 : -1;
441 extract_pkgname(int fd
)
446 struct archive_entry
*entry
;
451 a
= archive_read_new();
452 archive_read_support_compression_all(a
);
453 archive_read_support_format_all(a
);
454 if (archive_read_open_fd(a
, fd
, 1024)) {
455 warnx("Cannot open binary package: %s",
456 archive_error_string(a
));
457 archive_read_finish(a
);
461 r
= archive_read_next_header(a
, &entry
);
462 if (r
!= ARCHIVE_OK
) {
463 warnx("Cannot extract package name: %s",
464 r
== ARCHIVE_EOF
? "EOF" : archive_error_string(a
));
465 archive_read_finish(a
);
468 if (strcmp(archive_entry_pathname(entry
), "+CONTENTS") != 0) {
469 warnx("Invalid binary package, doesn't start with +CONTENTS");
470 archive_read_finish(a
);
473 if (archive_entry_size(entry
) > SSIZE_MAX
- 1) {
474 warnx("+CONTENTS too large to process");
475 archive_read_finish(a
);
479 len
= archive_entry_size(entry
);
480 buf
= xmalloc(len
+ 1);
482 if (archive_read_data(a
, buf
, len
) != len
) {
483 warnx("Short read when extracing +CONTENTS");
485 archive_read_finish(a
);
490 archive_read_finish(a
);
492 parse_plist(&plist
, buf
);
494 p
= find_plist(&plist
, PLIST_NAME
);
496 buf
= xstrdup(p
->name
);
498 warnx("Invalid PLIST: missing @name");
503 if (lseek(fd
, 0, SEEK_SET
) != 0) {
504 warn("Cannot seek in archive");
512 static const char hash_template
[] =
517 "algorithm: SHA512\n"
518 "block size: 65536\n"
522 static const char hash_trailer
[] = "end pkgsrc signature\n";
526 pkg_sign_x509(const char *name
, const char *output
, const char *key_file
, const char *cert_file
)
529 struct archive_entry
*entry
, *hash_entry
, *sign_entry
;
532 char *hash_file
, *signature_file
, *tmp
, *pkgname
, hash
[SHA512_DIGEST_STRING_LENGTH
];
533 unsigned char block
[65536];
535 size_t block_len
, signature_len
;
537 if ((fd
= open(name
, O_RDONLY
)) == -1)
538 err(EXIT_FAILURE
, "Cannot open binary package %s", name
);
539 if (fstat(fd
, &sb
) == -1)
540 err(EXIT_FAILURE
, "Cannot stat %s", name
);
542 entry
= archive_entry_new();
543 archive_entry_copy_stat(entry
, &sb
);
545 pkgname
= extract_pkgname(fd
);
546 hash_file
= xasprintf(hash_template
, pkgname
,
547 (long long)archive_entry_size(entry
));
550 for (i
= 0; i
< archive_entry_size(entry
); i
+= block_len
) {
551 if (i
+ (off_t
)sizeof(block
) < archive_entry_size(entry
))
552 block_len
= sizeof(block
);
554 block_len
= archive_entry_size(entry
) % sizeof(block
);
555 if (read(fd
, block
, block_len
) != (ssize_t
)block_len
)
556 err(2, "short read");
557 hash_block(block
, block_len
, hash
);
558 tmp
= xasprintf("%s%s\n", hash_file
, hash
);
562 tmp
= xasprintf("%s%s", hash_file
, hash_trailer
);
566 if (easy_pkcs7_sign(hash_file
, strlen(hash_file
), &signature_file
,
567 &signature_len
, key_file
, cert_file
))
568 err(EXIT_FAILURE
, "Cannot sign hash file");
570 lseek(fd
, 0, SEEK_SET
);
572 sign_entry
= archive_entry_clone(entry
);
573 hash_entry
= archive_entry_clone(entry
);
574 pkgname
= strrchr(name
, '/');
575 archive_entry_set_pathname(entry
, pkgname
!= NULL
? pkgname
+ 1 : name
);
576 archive_entry_set_pathname(hash_entry
, HASH_FNAME
);
577 archive_entry_set_pathname(sign_entry
, SIGNATURE_FNAME
);
578 archive_entry_set_size(hash_entry
, strlen(hash_file
));
579 archive_entry_set_size(sign_entry
, signature_len
);
581 pkg
= archive_write_new();
582 archive_write_set_compression_none(pkg
);
583 archive_write_set_format_ar_bsd(pkg
);
584 archive_write_open_filename(pkg
, output
);
586 archive_write_header(pkg
, hash_entry
);
587 archive_write_data(pkg
, hash_file
, strlen(hash_file
));
588 archive_write_finish_entry(pkg
);
589 archive_entry_free(hash_entry
);
591 archive_write_header(pkg
, sign_entry
);
592 archive_write_data(pkg
, signature_file
, signature_len
);
593 archive_write_finish_entry(pkg
);
594 archive_entry_free(sign_entry
);
596 size
= archive_entry_size(entry
);
597 archive_write_header(pkg
, entry
);
599 for (i
= 0; i
< size
; i
+= block_len
) {
600 if (i
+ (off_t
)sizeof(block
) < size
)
601 block_len
= sizeof(block
);
603 block_len
= size
% sizeof(block
);
604 if (read(fd
, block
, block_len
) != (ssize_t
)block_len
)
605 err(2, "short read");
606 archive_write_data(pkg
, block
, block_len
);
608 archive_write_finish_entry(pkg
);
609 archive_entry_free(entry
);
611 archive_write_finish(pkg
);
620 pkg_sign_gpg(const char *name
, const char *output
)
623 struct archive_entry
*entry
, *hash_entry
, *sign_entry
;
626 char *hash_file
, *signature_file
, *tmp
, *pkgname
, hash
[SHA512_DIGEST_STRING_LENGTH
];
627 unsigned char block
[65536];
629 size_t block_len
, signature_len
;
631 if ((fd
= open(name
, O_RDONLY
)) == -1)
632 err(EXIT_FAILURE
, "Cannot open binary package %s", name
);
633 if (fstat(fd
, &sb
) == -1)
634 err(EXIT_FAILURE
, "Cannot stat %s", name
);
636 entry
= archive_entry_new();
637 archive_entry_copy_stat(entry
, &sb
);
639 pkgname
= extract_pkgname(fd
);
640 hash_file
= xasprintf(hash_template
, pkgname
,
641 (long long)archive_entry_size(entry
));
644 for (i
= 0; i
< archive_entry_size(entry
); i
+= block_len
) {
645 if (i
+ (off_t
)sizeof(block
) < archive_entry_size(entry
))
646 block_len
= sizeof(block
);
648 block_len
= archive_entry_size(entry
) % sizeof(block
);
649 if (read(fd
, block
, block_len
) != (ssize_t
)block_len
)
650 err(2, "short read");
651 hash_block(block
, block_len
, hash
);
652 tmp
= xasprintf("%s%s\n", hash_file
, hash
);
656 tmp
= xasprintf("%s%s", hash_file
, hash_trailer
);
660 if (detached_gpg_sign(hash_file
, strlen(hash_file
), &signature_file
,
661 &signature_len
, gpg_keyring_sign
, gpg_sign_as
))
662 err(EXIT_FAILURE
, "Cannot sign hash file");
664 lseek(fd
, 0, SEEK_SET
);
666 sign_entry
= archive_entry_clone(entry
);
667 hash_entry
= archive_entry_clone(entry
);
668 pkgname
= strrchr(name
, '/');
669 archive_entry_set_pathname(entry
, pkgname
!= NULL
? pkgname
+ 1 : name
);
670 archive_entry_set_pathname(hash_entry
, HASH_FNAME
);
671 archive_entry_set_pathname(sign_entry
, GPG_SIGNATURE_FNAME
);
672 archive_entry_set_size(hash_entry
, strlen(hash_file
));
673 archive_entry_set_size(sign_entry
, signature_len
);
675 pkg
= archive_write_new();
676 archive_write_set_compression_none(pkg
);
677 archive_write_set_format_ar_bsd(pkg
);
678 archive_write_open_filename(pkg
, output
);
680 archive_write_header(pkg
, hash_entry
);
681 archive_write_data(pkg
, hash_file
, strlen(hash_file
));
682 archive_write_finish_entry(pkg
);
683 archive_entry_free(hash_entry
);
685 archive_write_header(pkg
, sign_entry
);
686 archive_write_data(pkg
, signature_file
, signature_len
);
687 archive_write_finish_entry(pkg
);
688 archive_entry_free(sign_entry
);
690 size
= archive_entry_size(entry
);
691 archive_write_header(pkg
, entry
);
693 for (i
= 0; i
< size
; i
+= block_len
) {
694 if (i
+ (off_t
)sizeof(block
) < size
)
695 block_len
= sizeof(block
);
697 block_len
= size
% sizeof(block
);
698 if (read(fd
, block
, block_len
) != (ssize_t
)block_len
)
699 err(2, "short read");
700 archive_write_data(pkg
, block
, block_len
);
702 archive_write_finish_entry(pkg
);
703 archive_entry_free(entry
);
705 archive_write_finish(pkg
);