2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
31 #ifdef HAVE_SYS_CDEFS_H
32 #include <sys/cdefs.h>
35 #if defined(__NetBSD__)
36 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
37 __RCSID("$NetBSD: netpgp.c,v 1.35 2009/12/22 06:53:26 agc Exp $");
40 #include <sys/types.h>
42 #include <sys/param.h>
45 #ifdef HAVE_SYS_RESOURCE_H
46 #include <sys/resource.h>
73 #include "packet-parse.h"
76 #include "packet-show.h"
78 #include "netpgpsdk.h"
81 #include "readerwriter.h"
82 #include "netpgpdefs.h"
86 /* read any gpg config file */
88 conffile(netpgp_t
*netpgp
, char *homedir
, char *userid
, size_t length
)
90 regmatch_t matchv
[10];
96 (void) snprintf(buf
, sizeof(buf
), "%s/gpg.conf", homedir
);
97 if ((fp
= fopen(buf
, "r")) == NULL
) {
100 (void) memset(&keyre
, 0x0, sizeof(keyre
));
101 (void) regcomp(&keyre
, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
103 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
104 if (regexec(&keyre
, buf
, 10, matchv
, 0) == 0) {
105 (void) memcpy(userid
, &buf
[(int)matchv
[1].rm_so
],
106 MIN((unsigned)(matchv
[1].rm_eo
-
107 matchv
[1].rm_so
), length
));
108 (void) fprintf(stderr
,
109 "netpgp: default key set to \"%.*s\"\n",
110 (int)(matchv
[1].rm_eo
- matchv
[1].rm_so
),
111 &buf
[(int)matchv
[1].rm_so
]);
118 /* small function to pretty print an 8-character raw userid */
120 userid_to_id(const unsigned char *userid
, char *id
)
122 static const char *hexes
= "0123456789abcdef";
125 for (i
= 0; i
< 8 ; i
++) {
126 id
[i
* 2] = hexes
[(unsigned)(userid
[i
] & 0xf0) >> 4];
127 id
[(i
* 2) + 1] = hexes
[userid
[i
] & 0xf];
133 /* print out the successful signature information */
135 resultp(__ops_io_t
*io
,
137 __ops_validation_t
*res
,
138 __ops_keyring_t
*ring
)
140 const __ops_key_t
*pubkey
;
143 char id
[MAX_ID_LENGTH
+ 1];
145 for (i
= 0; i
< res
->validc
; i
++) {
146 (void) fprintf(io
->res
,
147 "Good signature for %s made %susing %s key %s\n",
149 ctime(&res
->valid_sigs
[i
].birthtime
),
150 __ops_show_pka(res
->valid_sigs
[i
].key_alg
),
151 userid_to_id(res
->valid_sigs
[i
].signer_id
, id
));
153 pubkey
= __ops_getkeybyid(io
, ring
,
154 (const unsigned char *) res
->valid_sigs
[i
].signer_id
,
156 __ops_print_keydata(io
, pubkey
, "pub", &pubkey
->key
.pubkey
);
160 /* check there's enough space in the arrays */
162 size_arrays(netpgp_t
*netpgp
, unsigned needed
)
166 if (netpgp
->size
== 0) {
167 /* only get here first time around */
168 netpgp
->size
= needed
;
169 if ((netpgp
->name
= calloc(sizeof(char *), needed
)) == NULL
) {
170 (void) fprintf(stderr
, "size_arrays: bad alloc\n");
173 if ((netpgp
->value
= calloc(sizeof(char *), needed
)) == NULL
) {
175 (void) fprintf(stderr
, "size_arrays: bad alloc\n");
178 } else if (netpgp
->c
== netpgp
->size
) {
179 /* only uses 'needed' when filled array */
180 netpgp
->size
+= needed
;
181 temp
= realloc(netpgp
->name
, sizeof(char *) * needed
);
183 (void) fprintf(stderr
, "size_arrays: bad alloc\n");
187 temp
= realloc(netpgp
->value
, sizeof(char *) * needed
);
189 (void) fprintf(stderr
, "size_arrays: bad alloc\n");
192 netpgp
->value
= temp
;
197 /* find the name in the array */
199 findvar(netpgp_t
*netpgp
, const char *name
)
203 for (i
= 0 ; i
< netpgp
->c
&& strcmp(netpgp
->name
[i
], name
) != 0; i
++) {
205 return (i
== netpgp
->c
) ? -1 : (int)i
;
208 /* read a keyring and return it */
210 readkeyring(netpgp_t
*netpgp
, const char *name
)
212 __ops_keyring_t
*keyring
;
213 const unsigned noarmor
= 0;
218 homedir
= netpgp_getvar(netpgp
, "homedir");
219 if ((filename
= netpgp_getvar(netpgp
, name
)) == NULL
) {
220 (void) snprintf(f
, sizeof(f
), "%s/%s.gpg", homedir
, name
);
223 if ((keyring
= calloc(1, sizeof(*keyring
))) == NULL
) {
224 (void) fprintf(stderr
, "readkeyring: bad alloc\n");
227 if (!__ops_keyring_fileread(keyring
, noarmor
, filename
)) {
229 (void) fprintf(stderr
, "Can't read %s %s\n", name
, filename
);
232 netpgp_setvar(netpgp
, name
, filename
);
236 /* read keys from ssh key files */
238 readsshkeys(netpgp_t
*netpgp
, char *homedir
)
240 __ops_keyring_t
*pubring
;
241 __ops_keyring_t
*secring
;
245 if ((filename
= netpgp_getvar(netpgp
, "sshkeyfile")) == NULL
) {
246 (void) snprintf(f
, sizeof(f
), "%s/.ssh/is_rsa.pub", homedir
);
249 if ((pubring
= calloc(1, sizeof(*pubring
))) == NULL
) {
250 (void) fprintf(stderr
, "readsshkeys: bad alloc\n");
253 if (!__ops_ssh2_readkeys(netpgp
->io
, pubring
, NULL
, filename
, NULL
)) {
255 (void) fprintf(stderr
, "readsshkeys: can't read %s\n",
259 netpgp
->pubring
= pubring
;
260 netpgp_setvar(netpgp
, "sshpubfile", filename
);
261 /* try to take the ".pub" off the end */
263 f
[strlen(f
) - 4] = 0x0;
265 (void) snprintf(f
, sizeof(f
), "%.*s",
266 (int)strlen(filename
) - 4, filename
);
269 if ((secring
= calloc(1, sizeof(*secring
))) == NULL
) {
270 (void) fprintf(stderr
, "readsshkeys: bad alloc\n");
273 if (__ops_ssh2_readkeys(netpgp
->io
, pubring
, secring
, NULL
, filename
)) {
274 netpgp
->secring
= secring
;
275 netpgp_setvar(netpgp
, "sshsecfile", filename
);
277 (void) fprintf(stderr
, "readsshkeys: can't read sec %s (%d)\n",
283 /* set ssh uid to first one in ring */
285 set_ssh_userid(__ops_keyring_t
*pubring
, char *id
, size_t len
)
291 (void) memset(id
, 0x0, len
);
292 src
= pubring
->keys
[0].key_id
;
293 for (i
= 0, n
= 0 ; i
< OPS_KEY_ID_SIZE
; i
+= 2) {
294 n
+= snprintf(&id
[n
], len
- n
, "%02x%02x", src
[i
], src
[i
+ 1]);
299 /***************************************************************************/
300 /* exported functions start here */
301 /***************************************************************************/
303 /* initialise a netpgp_t structure */
305 netpgp_init(netpgp_t
*netpgp
)
308 char id
[MAX_ID_LENGTH
];
316 #ifdef HAVE_SYS_RESOURCE_H
319 coredumps
= netpgp_getvar(netpgp
, "coredumps") != NULL
;
321 (void) memset(&limit
, 0x0, sizeof(limit
));
322 if (setrlimit(RLIMIT_CORE
, &limit
) != 0) {
323 (void) fprintf(stderr
,
324 "netpgp_init: warning - can't turn off core dumps\n");
331 if ((io
= calloc(1, sizeof(*io
))) == NULL
) {
332 (void) fprintf(stderr
, "netpgp_init: bad alloc\n");
336 if ((stream
= netpgp_getvar(netpgp
, "stdout")) != NULL
&&
337 strcmp(stream
, "stderr") == 0) {
341 if ((stream
= netpgp_getvar(netpgp
, "stderr")) != NULL
&&
342 strcmp(stream
, "stdout") == 0) {
345 if ((results
= netpgp_getvar(netpgp
, "results")) == NULL
) {
347 } else if ((io
->res
= fopen(results
, "w")) == NULL
) {
348 (void) fprintf(io
->errs
, "Can't open results %s for writing\n",
354 (void) fprintf(io
->errs
,
355 "netpgp: warning: core dumps enabled\n");
357 if ((homedir
= netpgp_getvar(netpgp
, "homedir")) == NULL
) {
358 (void) fprintf(io
->errs
, "netpgp: bad homedir\n");
361 /* read from either gpg files or ssh keys */
362 if (netpgp_getvar(netpgp
, "ssh keys") == NULL
) {
363 if ((userid
= netpgp_getvar(netpgp
, "userid")) == NULL
) {
364 (void) memset(id
, 0x0, sizeof(id
));
365 (void) conffile(netpgp
, homedir
, id
, sizeof(id
));
367 netpgp_setvar(netpgp
, "userid", userid
= id
);
370 if (userid
== NULL
) {
371 if (netpgp_getvar(netpgp
, "need userid") != NULL
) {
372 (void) fprintf(io
->errs
,
373 "Cannot find user id\n");
377 (void) netpgp_setvar(netpgp
, "userid", userid
);
379 netpgp
->pubring
= readkeyring(netpgp
, "pubring");
380 if (netpgp
->pubring
== NULL
) {
381 (void) fprintf(io
->errs
, "Can't read pub keyring\n");
384 netpgp
->secring
= readkeyring(netpgp
, "secring");
385 if (netpgp
->secring
== NULL
) {
386 (void) fprintf(io
->errs
, "Can't read sec keyring\n");
390 if (!readsshkeys(netpgp
, homedir
)) {
391 (void) fprintf(io
->errs
, "Can't read ssh pub key\n");
394 if ((userid
= netpgp_getvar(netpgp
, "userid")) == NULL
) {
395 set_ssh_userid(netpgp
->pubring
, id
, sizeof(id
));
396 netpgp_setvar(netpgp
, "userid", userid
= id
);
398 if (userid
== NULL
) {
399 if (netpgp_getvar(netpgp
, "need userid") != NULL
) {
400 (void) fprintf(io
->errs
,
401 "Cannot find user id\n");
405 (void) netpgp_setvar(netpgp
, "userid", userid
);
408 if ((passfd
= netpgp_getvar(netpgp
, "pass-fd")) != NULL
&&
409 (netpgp
->passfp
= fdopen(atoi(passfd
), "r")) == NULL
) {
410 (void) fprintf(io
->errs
, "Can't open fd %s for reading\n",
417 /* finish off with the netpgp_t struct */
419 netpgp_end(netpgp_t
*netpgp
)
423 for (i
= 0 ; i
< netpgp
->c
; i
++) {
424 if (netpgp
->name
[i
] != NULL
) {
425 free(netpgp
->name
[i
]);
427 if (netpgp
->value
[i
] != NULL
) {
428 free(netpgp
->value
[i
]);
431 if (netpgp
->name
!= NULL
) {
434 if (netpgp
->value
!= NULL
) {
437 if (netpgp
->pubring
!= NULL
) {
438 __ops_keyring_free(netpgp
->pubring
);
440 if (netpgp
->secring
!= NULL
) {
441 __ops_keyring_free(netpgp
->secring
);
447 /* list the keys in a keyring */
449 netpgp_list_keys(netpgp_t
*netpgp
)
451 return __ops_keyring_list(netpgp
->io
, netpgp
->pubring
);
454 /* find and list some keys in a keyring */
456 netpgp_match_list_keys(netpgp_t
*netpgp
, char *name
)
458 const __ops_key_t
*key
;
465 key
= __ops_getnextkeybyname(netpgp
->io
, netpgp
->pubring
,
468 __ops_sprint_keydata(key
, &data
, "pub",
470 printf("%s\n", data
);
475 } while (key
!= NULL
);
476 printf("Found %u key%s\n", found
, (found
== 1) ? "" : "s");
480 /* find a key in a keyring */
482 netpgp_find_key(netpgp_t
*netpgp
, char *id
)
488 (void) fprintf(io
->errs
, "NULL id to search for\n");
491 return __ops_getkeybyname(netpgp
->io
, netpgp
->pubring
, id
) != NULL
;
494 /* get a key in a keyring */
496 netpgp_get_key(netpgp_t
*netpgp
, const char *id
)
498 const __ops_key_t
*key
;
504 (void) fprintf(io
->errs
, "NULL id to search for\n");
507 key
= __ops_getkeybyname(netpgp
->io
, netpgp
->pubring
, id
);
509 (void) fprintf(io
->errs
, "Can't find key '%s'\n", id
);
512 return (__ops_sprint_keydata(key
, &newkey
, "pub",
513 &key
->key
.pubkey
) > 0) ? newkey
: NULL
;
516 /* export a given key */
518 netpgp_export_key(netpgp_t
*netpgp
, char *userid
)
520 const __ops_key_t
*keypair
;
524 if (userid
== NULL
) {
525 userid
= netpgp_getvar(netpgp
, "userid");
527 keypair
= __ops_getkeybyname(io
, netpgp
->pubring
, userid
);
528 if (keypair
== NULL
) {
529 (void) fprintf(io
->errs
,
530 "Cannot find own key \"%s\" in keyring\n", userid
);
533 return __ops_export_key(keypair
, NULL
);
536 /* import a key into our keyring */
538 netpgp_import_key(netpgp_t
*netpgp
, char *f
)
540 const unsigned noarmor
= 0;
541 const unsigned armor
= 1;
546 if ((done
= __ops_keyring_fileread(netpgp
->pubring
, noarmor
, f
)) == 0) {
547 done
= __ops_keyring_fileread(netpgp
->pubring
, armor
, f
);
550 (void) fprintf(io
->errs
, "Cannot import key from file %s\n",
554 return __ops_keyring_list(io
, netpgp
->pubring
);
557 /* generate a new key */
559 netpgp_generate_key(netpgp_t
*netpgp
, char *id
, int numbits
)
561 __ops_key_t
*keypair
;
563 __ops_output_t
*create
;
564 const unsigned noarmor
= 0;
569 (void) memset(&uid
, 0x0, sizeof(uid
));
571 /* generate a new key for 'id' */
572 uid
.userid
= (unsigned char *) id
;
573 keypair
= __ops_rsa_new_selfsign_key(numbits
, 65537UL, &uid
);
574 if (keypair
== NULL
) {
575 (void) fprintf(io
->errs
, "Cannot generate key\n");
578 /* write public key, and try to re-read it */
579 ringfile
= netpgp_getvar(netpgp
, "pubring");
580 fd
= __ops_setup_file_append(&create
, ringfile
);
581 if (!__ops_write_xfer_pubkey(create
, keypair
, noarmor
)) {
582 (void) fprintf(io
->errs
, "Cannot write pubkey\n");
585 __ops_teardown_file_write(create
, fd
);
586 __ops_keyring_free(netpgp
->pubring
);
587 if (!__ops_keyring_fileread(netpgp
->pubring
, noarmor
, ringfile
)) {
588 (void) fprintf(io
->errs
, "Cannot read pubring %s\n", ringfile
);
591 /* write secret key, and try to re-read it */
592 ringfile
= netpgp_getvar(netpgp
, "sec ring file");
593 fd
= __ops_setup_file_append(&create
, ringfile
);
594 if (!__ops_write_xfer_seckey(create
, keypair
, NULL
, 0, noarmor
)) {
595 (void) fprintf(io
->errs
, "Cannot write seckey\n");
598 __ops_teardown_file_write(create
, fd
);
599 __ops_keyring_free(netpgp
->secring
);
600 if (!__ops_keyring_fileread(netpgp
->secring
, noarmor
, ringfile
)) {
601 (void) fprintf(io
->errs
, "Can't read secring %s\n", ringfile
);
604 __ops_keydata_free(keypair
);
610 netpgp_encrypt_file(netpgp_t
*netpgp
,
616 const __ops_key_t
*keypair
;
617 const unsigned overwrite
= 1;
620 char outname
[MAXPATHLEN
];
624 (void) fprintf(io
->errs
,
625 "netpgp_encrypt_file: no filename specified\n");
628 if (userid
== NULL
) {
629 userid
= netpgp_getvar(netpgp
, "userid");
631 suffix
= (armored
) ? ".asc" : ".gpg";
632 keypair
= __ops_getkeybyname(io
, netpgp
->pubring
, userid
);
633 if (keypair
== NULL
) {
634 (void) fprintf(io
->errs
, "Userid '%s' not found in keyring\n",
639 (void) snprintf(outname
, sizeof(outname
), "%s%s", f
, suffix
);
642 return (int)__ops_encrypt_file(io
, f
, out
, keypair
, (unsigned)armored
,
646 #define ARMOR_HEAD "-----BEGIN PGP MESSAGE-----\r\n"
650 netpgp_decrypt_file(netpgp_t
*netpgp
, const char *f
, char *out
, int armored
)
652 const unsigned overwrite
= 1;
660 (void) fprintf(io
->errs
,
661 "netpgp_decrypt_file: no filename specified\n");
664 realarmour
= (unsigned)armored
;
665 if ((fp
= fopen(f
, "r")) == NULL
) {
666 (void) fprintf(io
->errs
,
667 "netpgp_decrypt_file: can't open '%s'\n", f
);
670 if (fgets(buf
, sizeof(buf
), fp
) == NULL
) {
673 realarmour
= (strcmp(buf
, ARMOR_HEAD
) == 0);
676 return __ops_decrypt_file(netpgp
->io
, f
, out
, netpgp
->secring
,
677 (unsigned)realarmour
, overwrite
,
678 netpgp
->passfp
, get_passphrase_cb
);
683 netpgp_sign_file(netpgp_t
*netpgp
,
691 const __ops_key_t
*keypair
;
692 __ops_seckey_t
*seckey
;
693 const unsigned overwrite
= 1;
700 (void) fprintf(io
->errs
,
701 "netpgp_sign_file: no filename specified\n");
704 if (userid
== NULL
) {
705 userid
= netpgp_getvar(netpgp
, "userid");
707 /* get key with which to sign */
708 keypair
= __ops_getkeybyname(io
, netpgp
->secring
, userid
);
709 if (keypair
== NULL
) {
710 (void) fprintf(io
->errs
, "Userid '%s' not found in keyring\n",
716 /* print out the user id */
717 __ops_print_keydata(io
, keypair
, "pub", &keypair
->key
.pubkey
);
718 if (netpgp_getvar(netpgp
, "ssh keys") == NULL
) {
719 /* now decrypt key */
720 seckey
= __ops_decrypt_seckey(keypair
);
721 if (seckey
== NULL
) {
722 (void) fprintf(io
->errs
, "Bad passphrase\n");
725 __ops_keyring_t
*secring
;
727 secring
= netpgp
->secring
;
728 seckey
= &secring
->keys
[0].key
.seckey
;
730 } while (seckey
== NULL
);
732 hashalg
= netpgp_getvar(netpgp
, "hash");
734 ret
= __ops_sign_detached(io
, f
, out
, seckey
, hashalg
);
736 ret
= __ops_sign_file(io
, f
, out
, seckey
, hashalg
,
737 (unsigned)armored
, (unsigned)cleartext
,
740 __ops_forget(seckey
, sizeof(*seckey
));
746 netpgp_verify_file(netpgp_t
*netpgp
, const char *in
, const char *out
, int armored
)
748 __ops_validation_t result
;
751 (void) memset(&result
, 0x0, sizeof(result
));
754 (void) fprintf(io
->errs
,
755 "netpgp_verify_file: no filename specified\n");
758 if (__ops_validate_file(io
, &result
, in
, out
, armored
,
760 resultp(io
, in
, &result
, netpgp
->pubring
);
763 if (result
.validc
+ result
.invalidc
+ result
.unknownc
== 0) {
764 (void) fprintf(io
->errs
,
765 "\"%s\": No signatures found - is this a signed file?\n",
768 (void) fprintf(io
->errs
,
769 "\"%s\": verification failure: %u invalid signatures, %u unknown signatures\n",
770 in
, result
.invalidc
, result
.unknownc
);
775 /* sign some memory */
777 netpgp_sign_memory(netpgp_t
*netpgp
,
783 const unsigned armored
,
784 const unsigned cleartext
)
786 const __ops_key_t
*keypair
;
787 __ops_seckey_t
*seckey
;
788 __ops_memory_t
*signedmem
;
795 (void) fprintf(io
->errs
,
796 "netpgp_sign_memory: no memory to sign\n");
799 if (userid
== NULL
) {
800 userid
= netpgp_getvar(netpgp
, "userid");
802 /* get key with which to sign */
803 keypair
= __ops_getkeybyname(io
, netpgp
->secring
, userid
);
804 if (keypair
== NULL
) {
805 (void) fprintf(io
->errs
, "Userid '%s' not found in keyring\n",
811 /* print out the user id */
812 __ops_print_keydata(io
, keypair
, "pub", &keypair
->key
.pubkey
);
813 /* now decrypt key */
814 seckey
= __ops_decrypt_seckey(keypair
);
815 if (seckey
== NULL
) {
816 (void) fprintf(io
->errs
, "Bad passphrase\n");
818 } while (seckey
== NULL
);
820 hashalg
= netpgp_getvar(netpgp
, "hash");
821 signedmem
= __ops_sign_buf(io
, mem
, size
, seckey
, hashalg
,
826 m
= MIN(__ops_mem_len(signedmem
), outsize
);
827 (void) memcpy(out
, __ops_mem_data(signedmem
), m
);
828 __ops_memory_free(signedmem
);
833 __ops_forget(seckey
, sizeof(*seckey
));
839 netpgp_verify_memory(netpgp_t
*netpgp
, const void *in
, const size_t size
,
840 void *out
, size_t outsize
, const int armored
)
842 __ops_validation_t result
;
843 __ops_memory_t
*signedmem
;
849 (void) memset(&result
, 0x0, sizeof(result
));
852 (void) fprintf(io
->errs
,
853 "netpgp_verify_memory: no memory to verify\n");
856 signedmem
= __ops_memory_new();
857 __ops_memory_add(signedmem
, in
, size
);
858 ret
= __ops_validate_mem(io
, &result
, signedmem
,
860 armored
, netpgp
->pubring
);
861 __ops_memory_free(signedmem
);
863 resultp(io
, "<stdin>", &result
, netpgp
->pubring
);
865 m
= MIN(__ops_mem_len(cat
), outsize
);
866 (void) memcpy(out
, __ops_mem_data(cat
), m
);
867 __ops_memory_free(cat
);
873 if (result
.validc
+ result
.invalidc
+ result
.unknownc
== 0) {
874 (void) fprintf(io
->errs
,
875 "No signatures found - is this memory signed?\n");
877 (void) fprintf(io
->errs
,
878 "memory verification failure: %u invalid signatures, %u unknown signatures\n",
879 result
.invalidc
, result
.unknownc
);
884 /* encrypt some memory */
886 netpgp_encrypt_memory(netpgp_t
*netpgp
,
894 const __ops_key_t
*keypair
;
901 (void) fprintf(io
->errs
,
902 "netpgp_encrypt_buf: no memory to encrypt\n");
905 if (userid
== NULL
) {
906 userid
= netpgp_getvar(netpgp
, "userid");
908 keypair
= __ops_getkeybyname(io
, netpgp
->pubring
, userid
);
909 if (keypair
== NULL
) {
910 (void) fprintf(io
->errs
, "Userid '%s' not found in keyring\n",
915 (void) fprintf(io
->errs
,
916 "netpgp_encrypt_buf: input and output bufs need to be different\n");
919 if (outsize
< insize
) {
920 (void) fprintf(io
->errs
,
921 "netpgp_encrypt_buf: input size is larger than output size\n");
924 enc
= __ops_encrypt_buf(io
, in
, insize
, keypair
, (unsigned)armored
);
925 m
= MIN(__ops_mem_len(enc
), outsize
);
926 (void) memcpy(out
, __ops_mem_data(enc
), m
);
927 __ops_memory_free(enc
);
931 /* decrypt a chunk of memory */
933 netpgp_decrypt_memory(netpgp_t
*netpgp
, const void *input
, const size_t insize
,
934 char *out
, size_t outsize
, const int armored
)
942 realarmour
= (unsigned) armored
;
944 (void) fprintf(io
->errs
,
945 "netpgp_decrypt_memory: no memory\n");
948 realarmour
= (strncmp(input
, ARMOR_HEAD
, sizeof(ARMOR_HEAD
) - 1) == 0);
949 mem
= __ops_decrypt_buf(netpgp
->io
, input
, insize
, netpgp
->secring
,
950 realarmour
, netpgp
->passfp
,
952 m
= MIN(__ops_mem_len(mem
), outsize
);
953 (void) memcpy(out
, __ops_mem_data(mem
), m
);
954 __ops_memory_free(mem
);
958 /* wrappers for the ops_debug_level functions we added to openpgpsdk */
960 /* set the debugging level per filename */
962 netpgp_set_debug(const char *f
)
964 return __ops_set_debug_level(f
);
967 /* get the debugging level per filename */
969 netpgp_get_debug(const char *f
)
971 return __ops_get_debug_level(f
);
974 /* return the version for the library */
976 netpgp_get_info(const char *type
)
978 return __ops_get_info(type
);
981 /* list all the packets in a file */
983 netpgp_list_packets(netpgp_t
*netpgp
, char *f
, int armour
, char *pubringname
)
985 __ops_keyring_t
*keyring
;
986 const unsigned noarmor
= 0;
988 char ringname
[MAXPATHLEN
];
994 (void) fprintf(io
->errs
, "No file containing packets\n");
997 homedir
= netpgp_getvar(netpgp
, "homedir");
998 if (pubringname
== NULL
) {
999 (void) snprintf(ringname
, sizeof(ringname
),
1000 "%s/pubring.gpg", homedir
);
1001 pubringname
= ringname
;
1003 if ((keyring
= calloc(1, sizeof(*keyring
))) == NULL
) {
1004 (void) fprintf(io
->errs
, "netpgp_list_packets: bad alloc\n");
1007 if (!__ops_keyring_fileread(keyring
, noarmor
, pubringname
)) {
1009 (void) fprintf(io
->errs
, "Cannot read pub keyring %s\n",
1013 netpgp
->pubring
= keyring
;
1014 netpgp_setvar(netpgp
, "pubring", pubringname
);
1015 ret
= __ops_list_packets(io
, f
, (unsigned)armour
, keyring
,
1022 /* set a variable */
1024 netpgp_setvar(netpgp_t
*netpgp
, const char *name
, const char *value
)
1028 if ((i
= findvar(netpgp
, name
)) < 0) {
1029 /* add the element to the array */
1030 if (size_arrays(netpgp
, netpgp
->size
+ 15)) {
1031 netpgp
->name
[i
= netpgp
->c
++] = strdup(name
);
1034 /* replace the element in the array */
1035 if (netpgp
->value
[i
]) {
1036 free(netpgp
->value
[i
]);
1037 netpgp
->value
[i
] = NULL
;
1040 /* sanity checks for range of values */
1041 if (strcmp(name
, "hash") == 0 || strcmp(name
, "algorithm") == 0) {
1042 if (__ops_str_to_hash_alg(value
) == OPS_HASH_UNKNOWN
) {
1046 netpgp
->value
[i
] = strdup(value
);
1050 /* get a variable's value (NULL if not set) */
1052 netpgp_getvar(netpgp_t
*netpgp
, const char *name
)
1056 return ((i
= findvar(netpgp
, name
)) < 0) ? NULL
: netpgp
->value
[i
];
1059 /* increment a value */
1061 netpgp_incvar(netpgp_t
*netpgp
, const char *name
, const int delta
)
1068 if ((cp
= netpgp_getvar(netpgp
, name
)) != NULL
) {
1071 (void) snprintf(num
, sizeof(num
), "%d", val
+ delta
);
1072 netpgp_setvar(netpgp
, name
, num
);
1076 /* set the home directory value to "home/subdir" */
1078 netpgp_set_homedir(netpgp_t
*netpgp
, char *home
, const char *subdir
, const int quiet
)
1085 (void) fprintf(stderr
, "NULL HOME directory\n");
1089 (void) snprintf(d
, sizeof(d
), "%s%s", home
, (subdir
) ? subdir
: "");
1090 if (stat(d
, &st
) == 0) {
1091 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
1092 netpgp_setvar(netpgp
, "homedir", d
);
1095 (void) fprintf(stderr
, "netpgp: homedir \"%s\" is not a dir\n",
1100 (void) fprintf(stderr
,
1101 "netpgp: warning homedir \"%s\" not found\n", d
);