1 /* $NetBSD: gpgsig.c,v 1.3 2009/08/02 17:56:45 joerg Exp $ */
10 __RCSID("$NetBSD: gpgsig.c,v 1.3 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
43 #include <nbcompat/err.h>
48 #include <nbcompat/stdlib.h>
56 verify_signature(const char *input
, size_t input_len
, const char *keyring
,
57 const char *detached_signature
)
59 const char *argv
[8], **argvp
;
64 err(EXIT_FAILURE
, "cannot create input pipes");
68 err(EXIT_FAILURE
, "cannot fork GPG process");
72 if (dup2(fd
[0], STDIN_FILENO
) == -1) {
73 static const char err_msg
[] =
74 "cannot redirect stdin of GPG process\n";
75 write(STDERR_FILENO
, err_msg
, sizeof(err_msg
) - 1);
81 *argvp
++ = "--verify";
82 if (keyring
!= NULL
) {
83 *argvp
++ = "--no-default-keyring";
84 *argvp
++ = "--keyring";
88 if (detached_signature
!= NULL
)
89 *argvp
++ = detached_signature
;
94 execvp(gpg_cmd
, __UNCONST(argv
));
98 if (write(fd
[1], input
, input_len
) != (ssize_t
)input_len
)
99 errx(EXIT_FAILURE
, "Short read from GPG");
101 waitpid(child
, &status
, 0);
103 errx(EXIT_FAILURE
, "GPG could not verify the signature");
107 inline_gpg_verify(const char *content
, size_t len
, const char *keyring
)
109 verify_signature(content
, len
, keyring
, NULL
);
115 detached_gpg_verify(const char *content
, size_t len
,
116 const char *signature
, size_t signature_len
, const char *keyring
)
123 if (gpg_cmd
== NULL
) {
124 warnx("GPG variable not set, failing signature check");
128 if ((tmpdir
= getenv("TMPDIR")) == NULL
)
130 tempsig
= xasprintf("%s/pkg_install.XXXXXX", tmpdir
);
132 fd
= mkstemp(tempsig
);
134 warnx("Creating temporary file for GPG signature failed");
138 while (signature_len
) {
139 ret
= write(fd
, signature
, signature_len
);
141 err(EXIT_FAILURE
, "Write to GPG failed");
143 errx(EXIT_FAILURE
, "Short write to GPG");
144 signature_len
-= ret
;
148 verify_signature(content
, len
, keyring
, tempsig
);
158 detached_gpg_sign(const char *content
, size_t len
, char **sig
, size_t *sig_len
,
159 const char *keyring
, const char *user
)
161 const char *argv
[12], **argvp
;
163 int fd_in
[2], fd_out
[2], status
;
168 errx(EXIT_FAILURE
, "GPG variable not set");
170 if (pipe(fd_in
) == -1)
171 err(EXIT_FAILURE
, "cannot create input pipes");
172 if (pipe(fd_out
) == -1)
173 err(EXIT_FAILURE
, "cannot create output pipes");
177 err(EXIT_FAILURE
, "cannot fork GPG process");
181 if (dup2(fd_in
[0], STDIN_FILENO
) == -1) {
182 static const char err_msg
[] =
183 "cannot redirect stdin of GPG process\n";
184 write(STDERR_FILENO
, err_msg
, sizeof(err_msg
) - 1);
190 close(STDOUT_FILENO
);
191 if (dup2(fd_out
[1], STDOUT_FILENO
) == -1) {
192 static const char err_msg
[] =
193 "cannot redirect stdout of GPG process\n";
194 write(STDERR_FILENO
, err_msg
, sizeof(err_msg
) - 1);
201 *argvp
++ = "--detach-sign";
202 *argvp
++ = "--armor";
203 *argvp
++ = "--output";
206 *argvp
++ = "--local-user";
209 if (keyring
!= NULL
) {
210 *argvp
++ = "--no-default-keyring";
211 *argvp
++ = "--secret-keyring";
218 execvp(gpg_cmd
, __UNCONST(argv
));
222 if (write(fd_in
[1], content
, len
) != (ssize_t
)len
)
223 errx(EXIT_FAILURE
, "Short read from GPG");
227 *sig
= xmalloc(allocated
);
232 while ((ret
= read(fd_out
[0], *sig
+ *sig_len
,
233 allocated
- *sig_len
)) > 0) {
235 if (*sig_len
== allocated
) {
237 *sig
= xrealloc(*sig
, allocated
);
243 waitpid(child
, &status
, 0);
245 errx(EXIT_FAILURE
, "GPG could not create signature");