12232f800Sagc /*-
2b15ec256Sagc * Copyright (c) 2009,2010 The NetBSD Foundation, Inc.
32232f800Sagc * All rights reserved.
42232f800Sagc *
52232f800Sagc * This code is derived from software contributed to The NetBSD Foundation
62232f800Sagc * by Alistair Crooks (agc@NetBSD.org)
72232f800Sagc *
82232f800Sagc * Redistribution and use in source and binary forms, with or without
92232f800Sagc * modification, are permitted provided that the following conditions
102232f800Sagc * are met:
112232f800Sagc * 1. Redistributions of source code must retain the above copyright
122232f800Sagc * notice, this list of conditions and the following disclaimer.
132232f800Sagc * 2. Redistributions in binary form must reproduce the above copyright
142232f800Sagc * notice, this list of conditions and the following disclaimer in the
152232f800Sagc * documentation and/or other materials provided with the distribution.
162232f800Sagc *
172232f800Sagc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
182232f800Sagc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
192232f800Sagc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202232f800Sagc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
212232f800Sagc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222232f800Sagc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232232f800Sagc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
242232f800Sagc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
252232f800Sagc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
262232f800Sagc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
272232f800Sagc * POSSIBILITY OF SUCH DAMAGE.
282232f800Sagc */
2993bf6008Sagc /*
3093bf6008Sagc * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
3193bf6008Sagc * All rights reserved.
3293bf6008Sagc * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
3393bf6008Sagc * their moral rights under the UK Copyright Design and Patents Act 1988 to
3493bf6008Sagc * be recorded as the authors of this copyright work.
3593bf6008Sagc *
3693bf6008Sagc * Licensed under the Apache License, Version 2.0 (the "License"); you may not
3793bf6008Sagc * use this file except in compliance with the License.
3893bf6008Sagc *
3993bf6008Sagc * You may obtain a copy of the License at
4093bf6008Sagc * http://www.apache.org/licenses/LICENSE-2.0
4193bf6008Sagc *
4293bf6008Sagc * Unless required by applicable law or agreed to in writing, software
4393bf6008Sagc * distributed under the License is distributed on an "AS IS" BASIS,
4493bf6008Sagc * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4593bf6008Sagc *
4693bf6008Sagc * See the License for the specific language governing permissions and
4793bf6008Sagc * limitations under the License.
4893bf6008Sagc */
4993bf6008Sagc
5093bf6008Sagc /** \file
5193bf6008Sagc */
5293bf6008Sagc #include "config.h"
5393bf6008Sagc
5457324b9fSagc #ifdef HAVE_SYS_CDEFS_H
5557324b9fSagc #include <sys/cdefs.h>
5657324b9fSagc #endif
5757324b9fSagc
5857324b9fSagc #if defined(__NetBSD__)
5957324b9fSagc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60*0294a66bSjhigh __RCSID("$NetBSD: misc.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $");
6157324b9fSagc #endif
6257324b9fSagc
630df5e957Sagc #include <sys/types.h>
640df5e957Sagc #include <sys/stat.h>
650df5e957Sagc #include <sys/mman.h>
660df5e957Sagc
67fdfbba49Sagc #include <ctype.h>
68bcfd8565Sagc #include <stdarg.h>
69bcfd8565Sagc #include <stdio.h>
70bcfd8565Sagc #include <stdlib.h>
71bcfd8565Sagc #include <string.h>
72bcfd8565Sagc
73bcfd8565Sagc #ifdef HAVE_UNISTD_H
74bcfd8565Sagc #include <unistd.h>
75bcfd8565Sagc #endif
76bcfd8565Sagc
77732655c3Sagc #ifdef HAVE_OPENSSL_RAND_H
78efdd9dbaSagc #include <openssl/rand.h>
79732655c3Sagc #endif
80efdd9dbaSagc
8193bf6008Sagc #include "errors.h"
8293bf6008Sagc #include "packet.h"
8393bf6008Sagc #include "crypto.h"
8493bf6008Sagc #include "create.h"
8593bf6008Sagc #include "packet-parse.h"
8693bf6008Sagc #include "packet-show.h"
8793bf6008Sagc #include "signature.h"
88efdd9dbaSagc #include "netpgpsdk.h"
8993bf6008Sagc #include "netpgpdefs.h"
9093bf6008Sagc #include "memory.h"
9193bf6008Sagc #include "readerwriter.h"
9293bf6008Sagc #include "version.h"
936715e11aSagc #include "netpgpdigest.h"
9493bf6008Sagc
9593bf6008Sagc #ifdef WIN32
9693bf6008Sagc #define vsnprintf _vsnprintf
9793bf6008Sagc #endif
9893bf6008Sagc
99*0294a66bSjhigh struct ecdsa_map {
100*0294a66bSjhigh char *sname;
101*0294a66bSjhigh int nid;
102*0294a66bSjhigh int bits;
103*0294a66bSjhigh int len;
104*0294a66bSjhigh uint8_t oid[8];
105*0294a66bSjhigh } ecdsa_map[] = {
106*0294a66bSjhigh { "P-256", NID_X9_62_prime256v1, 256, 8, {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} },
107*0294a66bSjhigh { "P-384", NID_secp384r1, 384, 5, {0x2B, 0x81, 0x04, 0x00, 0x22} },
108*0294a66bSjhigh { "P-521", NID_secp521r1, 521, 5, {0x2B, 0x81, 0x04, 0x00, 0x23} },
109*0294a66bSjhigh { NULL, 0, 0, 0, {0} }
110*0294a66bSjhigh };
111d21b929eSagc
11293bf6008Sagc typedef struct {
113fc1f8641Sagc pgp_keyring_t *keyring;
11493bf6008Sagc } accumulate_t;
11593bf6008Sagc
11693bf6008Sagc /**
11793bf6008Sagc * \ingroup Core_Callbacks
11893bf6008Sagc */
119fc1f8641Sagc static pgp_cb_ret_t
accumulate_cb(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)120fc1f8641Sagc accumulate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
12193bf6008Sagc {
122fc1f8641Sagc const pgp_contents_t *content = &pkt->u;
123fc1f8641Sagc pgp_keyring_t *keyring;
12457324b9fSagc accumulate_t *accumulate;
1253118701fSmlelstv pgp_key_t *key;
12693bf6008Sagc
127fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
128520c968fSagc (void) fprintf(stderr, "accumulate callback: packet tag %u\n", pkt->tag);
129520c968fSagc }
130fc1f8641Sagc accumulate = pgp_callback_arg(cbinfo);
13157324b9fSagc keyring = accumulate->keyring;
1323118701fSmlelstv key = keyring->keyc > 0 ? &keyring->keys[keyring->keyc - 1] : NULL;
1333326c4c5Sagc switch (pkt->tag) {
134fc1f8641Sagc case PGP_PTAG_CT_PUBLIC_KEY:
135fc1f8641Sagc case PGP_PTAG_CT_PUBLIC_SUBKEY:
136fc1f8641Sagc pgp_add_to_pubring(keyring, &content->pubkey, pkt->tag);
137fc1f8641Sagc return PGP_KEEP_MEMORY;
138fc1f8641Sagc case PGP_PTAG_CT_SECRET_KEY:
139fc1f8641Sagc case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
140fc1f8641Sagc pgp_add_to_secring(keyring, &content->seckey);
141fc1f8641Sagc return PGP_KEEP_MEMORY;
142fc1f8641Sagc case PGP_PTAG_CT_USER_ID:
143fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
144ef1ef480Sagc (void) fprintf(stderr, "User ID: %s for key %d\n",
145d427c17dSagc content->userid,
146ef1ef480Sagc keyring->keyc - 1);
14793bf6008Sagc }
1483118701fSmlelstv if (key != NULL) {
1493118701fSmlelstv pgp_add_userid(key, content->userid);
150520c968fSagc } else {
1513118701fSmlelstv PGP_ERROR_1(cbinfo->errors, PGP_E_P_NO_USERID, "%s",
1523118701fSmlelstv "No key for userid found");
153520c968fSagc }
154fc1f8641Sagc return PGP_KEEP_MEMORY;
155fc1f8641Sagc case PGP_PARSER_PACKET_END:
1563118701fSmlelstv if (key != NULL) {
1573118701fSmlelstv switch (content->packet.tag) {
1583118701fSmlelstv case PGP_PTAG_CT_RESERVED:
1593118701fSmlelstv (void) fprintf(stderr, "Invalid packet tag\n");
1603118701fSmlelstv break;
1613118701fSmlelstv case PGP_PTAG_CT_PUBLIC_KEY:
1623118701fSmlelstv case PGP_PTAG_CT_USER_ID:
1633118701fSmlelstv break;
1643118701fSmlelstv default:
1653118701fSmlelstv pgp_add_subpacket(key, &content->packet);
1663118701fSmlelstv break;
1673118701fSmlelstv }
168fc1f8641Sagc return PGP_KEEP_MEMORY;
16957324b9fSagc }
170fc1f8641Sagc return PGP_RELEASE_MEMORY;
171fc1f8641Sagc case PGP_PARSER_ERROR:
172d427c17dSagc (void) fprintf(stderr, "Error: %s\n", content->error);
173fc1f8641Sagc return PGP_FINISHED;
174fc1f8641Sagc case PGP_PARSER_ERRCODE:
17557324b9fSagc (void) fprintf(stderr, "parse error: %s\n",
176fc1f8641Sagc pgp_errcode(content->errcode.errcode));
17793bf6008Sagc break;
17893bf6008Sagc default:
17993bf6008Sagc break;
18093bf6008Sagc }
18193bf6008Sagc /* XXX: we now exclude so many things, we should either drop this or */
18293bf6008Sagc /* do something to pass on copies of the stuff we keep */
183fc1f8641Sagc return pgp_stacked_callback(pkt, cbinfo);
18493bf6008Sagc }
18593bf6008Sagc
18693bf6008Sagc /**
18793bf6008Sagc * \ingroup Core_Parse
18893bf6008Sagc *
18993bf6008Sagc * Parse packets from an input stream until EOF or error.
19093bf6008Sagc *
19193bf6008Sagc * Key data found in the parsed data is added to #keyring.
19293bf6008Sagc *
19393bf6008Sagc * \param keyring Pointer to an existing keyring
19493bf6008Sagc * \param parse Options to use when parsing
19593bf6008Sagc */
19693bf6008Sagc int
pgp_parse_and_accumulate(pgp_keyring_t * keyring,pgp_stream_t * parse)197fc1f8641Sagc pgp_parse_and_accumulate(pgp_keyring_t *keyring, pgp_stream_t *parse)
19893bf6008Sagc {
19993bf6008Sagc accumulate_t accumulate;
200393ecd92Sagc const int printerrors = 1;
20157324b9fSagc int ret;
20293bf6008Sagc
2032232f800Sagc if (parse->readinfo.accumulate) {
204bcfd8565Sagc (void) fprintf(stderr,
205fc1f8641Sagc "pgp_parse_and_accumulate: already init\n");
206bcfd8565Sagc return 0;
207bcfd8565Sagc }
20893bf6008Sagc
20993bf6008Sagc (void) memset(&accumulate, 0x0, sizeof(accumulate));
21093bf6008Sagc
21193bf6008Sagc accumulate.keyring = keyring;
21293bf6008Sagc
213fc1f8641Sagc pgp_callback_push(parse, accumulate_cb, &accumulate);
2144b3a3e18Sagc parse->readinfo.accumulate = 1;
215fc1f8641Sagc ret = pgp_parse(parse, !printerrors);
21693bf6008Sagc
21757324b9fSagc return ret;
21893bf6008Sagc }
21993bf6008Sagc
22093bf6008Sagc
22193bf6008Sagc /** \file
22293bf6008Sagc * \brief Error Handling
22393bf6008Sagc */
22493bf6008Sagc #define ERRNAME(code) { code, #code }
22593bf6008Sagc
226fc1f8641Sagc static pgp_errcode_name_map_t errcode_name_map[] = {
227fc1f8641Sagc ERRNAME(PGP_E_OK),
228fc1f8641Sagc ERRNAME(PGP_E_FAIL),
229fc1f8641Sagc ERRNAME(PGP_E_SYSTEM_ERROR),
230fc1f8641Sagc ERRNAME(PGP_E_UNIMPLEMENTED),
23193bf6008Sagc
232fc1f8641Sagc ERRNAME(PGP_E_R),
233fc1f8641Sagc ERRNAME(PGP_E_R_READ_FAILED),
234fc1f8641Sagc ERRNAME(PGP_E_R_EARLY_EOF),
235fc1f8641Sagc ERRNAME(PGP_E_R_BAD_FORMAT),
236fc1f8641Sagc ERRNAME(PGP_E_R_UNCONSUMED_DATA),
23793bf6008Sagc
238fc1f8641Sagc ERRNAME(PGP_E_W),
239fc1f8641Sagc ERRNAME(PGP_E_W_WRITE_FAILED),
240fc1f8641Sagc ERRNAME(PGP_E_W_WRITE_TOO_SHORT),
24193bf6008Sagc
242fc1f8641Sagc ERRNAME(PGP_E_P),
243fc1f8641Sagc ERRNAME(PGP_E_P_NOT_ENOUGH_DATA),
244fc1f8641Sagc ERRNAME(PGP_E_P_UNKNOWN_TAG),
245fc1f8641Sagc ERRNAME(PGP_E_P_PACKET_CONSUMED),
246fc1f8641Sagc ERRNAME(PGP_E_P_MPI_FORMAT_ERROR),
24793bf6008Sagc
248fc1f8641Sagc ERRNAME(PGP_E_C),
24993bf6008Sagc
250fc1f8641Sagc ERRNAME(PGP_E_V),
251fc1f8641Sagc ERRNAME(PGP_E_V_BAD_SIGNATURE),
252fc1f8641Sagc ERRNAME(PGP_E_V_NO_SIGNATURE),
253fc1f8641Sagc ERRNAME(PGP_E_V_UNKNOWN_SIGNER),
25493bf6008Sagc
255fc1f8641Sagc ERRNAME(PGP_E_ALG),
256fc1f8641Sagc ERRNAME(PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG),
257fc1f8641Sagc ERRNAME(PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG),
258fc1f8641Sagc ERRNAME(PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG),
259fc1f8641Sagc ERRNAME(PGP_E_ALG_UNSUPPORTED_HASH_ALG),
26093bf6008Sagc
261fc1f8641Sagc ERRNAME(PGP_E_PROTO),
262fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT),
263fc1f8641Sagc ERRNAME(PGP_E_PROTO_UNKNOWN_SS),
264fc1f8641Sagc ERRNAME(PGP_E_PROTO_CRITICAL_SS_IGNORED),
265fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN),
266fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_SIGNATURE_VRSN),
267fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN),
268fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_PKSK_VRSN),
269fc1f8641Sagc ERRNAME(PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN),
270fc1f8641Sagc ERRNAME(PGP_E_PROTO_BAD_SK_CHECKSUM),
27193bf6008Sagc
27293bf6008Sagc {0x00, NULL}, /* this is the end-of-array marker */
27393bf6008Sagc };
27493bf6008Sagc
27593bf6008Sagc /**
27693bf6008Sagc * \ingroup Core_Errors
27793bf6008Sagc * \brief returns error code name
27893bf6008Sagc * \param errcode
27993bf6008Sagc * \return error code name or "Unknown"
28093bf6008Sagc */
28193bf6008Sagc const char *
pgp_errcode(const pgp_errcode_t errcode)282fc1f8641Sagc pgp_errcode(const pgp_errcode_t errcode)
28393bf6008Sagc {
284fc1f8641Sagc return (pgp_str_from_map((int) errcode,
285fc1f8641Sagc (pgp_map_t *) errcode_name_map));
28693bf6008Sagc }
28793bf6008Sagc
2889b753456Sagc /* generic grab new storage function */
2899b753456Sagc void *
pgp_new(size_t size)290fc1f8641Sagc pgp_new(size_t size)
2919b753456Sagc {
2929b753456Sagc void *vp;
2939b753456Sagc
2949b753456Sagc if ((vp = calloc(1, size)) == NULL) {
2959b753456Sagc (void) fprintf(stderr,
2969b753456Sagc "allocation failure for %" PRIsize "u bytes", size);
2979b753456Sagc }
2989b753456Sagc return vp;
2999b753456Sagc }
3009b753456Sagc
30193bf6008Sagc /**
30293bf6008Sagc * \ingroup Core_Errors
30393bf6008Sagc * \brief Pushes the given error on the given errorstack
30493bf6008Sagc * \param errstack Error stack to use
30593bf6008Sagc * \param errcode Code of error to push
306fc1f8641Sagc * \param sys_errno System errno (used if errcode=PGP_E_SYSTEM_ERROR)
30793bf6008Sagc * \param file Source filename where error occurred
30893bf6008Sagc * \param line Line in source file where error occurred
30993bf6008Sagc * \param fmt Comment
31093bf6008Sagc *
31193bf6008Sagc */
31293bf6008Sagc
31393bf6008Sagc void
pgp_push_error(pgp_error_t ** errstack,pgp_errcode_t errcode,int sys_errno,const char * file,int line,const char * fmt,...)314fc1f8641Sagc pgp_push_error(pgp_error_t **errstack, pgp_errcode_t errcode,
3154b3a3e18Sagc int sys_errno, const char *file, int line, const char *fmt,...)
31693bf6008Sagc {
31793bf6008Sagc /* first get the varargs and generate the comment */
318fc1f8641Sagc pgp_error_t *err;
319efdd9dbaSagc unsigned maxbuf = 128;
320efdd9dbaSagc va_list args;
321efdd9dbaSagc char *comment;
32293bf6008Sagc
323bcfd8565Sagc if ((comment = calloc(1, maxbuf + 1)) == NULL) {
324bcfd8565Sagc (void) fprintf(stderr, "calloc comment failure\n");
325bcfd8565Sagc return;
326bcfd8565Sagc }
32793bf6008Sagc
32893bf6008Sagc va_start(args, fmt);
32993bf6008Sagc vsnprintf(comment, maxbuf + 1, fmt, args);
33093bf6008Sagc va_end(args);
33193bf6008Sagc
33293bf6008Sagc /* alloc a new error and add it to the top of the stack */
33393bf6008Sagc
334814ccb85Sagc if ((err = calloc(1, sizeof(*err))) == NULL) {
335bcfd8565Sagc (void) fprintf(stderr, "calloc comment failure\n");
336bcfd8565Sagc return;
337bcfd8565Sagc }
33893bf6008Sagc
33993bf6008Sagc err->next = *errstack;
34093bf6008Sagc *errstack = err;
34193bf6008Sagc
34293bf6008Sagc /* fill in the details */
34393bf6008Sagc err->errcode = errcode;
34493bf6008Sagc err->sys_errno = sys_errno;
34593bf6008Sagc err->file = file;
34693bf6008Sagc err->line = line;
34793bf6008Sagc
34893bf6008Sagc err->comment = comment;
34993bf6008Sagc }
35093bf6008Sagc
35193bf6008Sagc /**
35293bf6008Sagc \ingroup Core_Errors
35393bf6008Sagc \brief print this error
35493bf6008Sagc \param err Error to print
35593bf6008Sagc */
35693bf6008Sagc void
pgp_print_error(pgp_error_t * err)357fc1f8641Sagc pgp_print_error(pgp_error_t *err)
35893bf6008Sagc {
35993bf6008Sagc printf("%s:%d: ", err->file, err->line);
360fc1f8641Sagc if (err->errcode == PGP_E_SYSTEM_ERROR) {
36193bf6008Sagc printf("system error %d returned from %s()\n", err->sys_errno,
36293bf6008Sagc err->comment);
3634b3a3e18Sagc } else {
364fc1f8641Sagc printf("%s, %s\n", pgp_errcode(err->errcode), err->comment);
36593bf6008Sagc }
3664b3a3e18Sagc }
36793bf6008Sagc
36893bf6008Sagc /**
36993bf6008Sagc \ingroup Core_Errors
37093bf6008Sagc \brief Print all errors on stack
37193bf6008Sagc \param errstack Error stack to print
37293bf6008Sagc */
37393bf6008Sagc void
pgp_print_errors(pgp_error_t * errstack)374fc1f8641Sagc pgp_print_errors(pgp_error_t *errstack)
37593bf6008Sagc {
376fc1f8641Sagc pgp_error_t *err;
37793bf6008Sagc
3784b3a3e18Sagc for (err = errstack; err != NULL; err = err->next) {
379fc1f8641Sagc pgp_print_error(err);
38093bf6008Sagc }
3814b3a3e18Sagc }
38293bf6008Sagc
38393bf6008Sagc /**
38493bf6008Sagc \ingroup Core_Errors
3854b3a3e18Sagc \brief Return 1 if given error is present anywhere on stack
38693bf6008Sagc \param errstack Error stack to check
38793bf6008Sagc \param errcode Error code to look for
38893bf6008Sagc \return 1 if found; else 0
38993bf6008Sagc */
39093bf6008Sagc int
pgp_has_error(pgp_error_t * errstack,pgp_errcode_t errcode)391fc1f8641Sagc pgp_has_error(pgp_error_t *errstack, pgp_errcode_t errcode)
39293bf6008Sagc {
393fc1f8641Sagc pgp_error_t *err;
394d21b929eSagc
39593bf6008Sagc for (err = errstack; err != NULL; err = err->next) {
3964b3a3e18Sagc if (err->errcode == errcode) {
39793bf6008Sagc return 1;
39893bf6008Sagc }
3994b3a3e18Sagc }
40093bf6008Sagc return 0;
40193bf6008Sagc }
40293bf6008Sagc
40393bf6008Sagc /**
40493bf6008Sagc \ingroup Core_Errors
40593bf6008Sagc \brief Frees all errors on stack
40693bf6008Sagc \param errstack Error stack to free
40793bf6008Sagc */
40893bf6008Sagc void
pgp_free_errors(pgp_error_t * errstack)409fc1f8641Sagc pgp_free_errors(pgp_error_t *errstack)
41093bf6008Sagc {
411fc1f8641Sagc pgp_error_t *next;
4124b3a3e18Sagc
41393bf6008Sagc while (errstack != NULL) {
41493bf6008Sagc next = errstack->next;
415814ccb85Sagc free(errstack->comment);
416814ccb85Sagc free(errstack);
41793bf6008Sagc errstack = next;
41893bf6008Sagc }
41993bf6008Sagc }
42093bf6008Sagc
42147561e26Sagc /* hash a 32-bit integer */
42247561e26Sagc static int
hash_uint32(pgp_hash_t * hash,uint32_t n)423fc1f8641Sagc hash_uint32(pgp_hash_t *hash, uint32_t n)
42447561e26Sagc {
42547561e26Sagc uint8_t ibuf[4];
42647561e26Sagc
42747561e26Sagc ibuf[0] = (uint8_t)(n >> 24) & 0xff;
42847561e26Sagc ibuf[1] = (uint8_t)(n >> 16) & 0xff;
42947561e26Sagc ibuf[2] = (uint8_t)(n >> 8) & 0xff;
43047561e26Sagc ibuf[3] = (uint8_t)n & 0xff;
43169d4f30fSagc (*hash->add)(hash, (const uint8_t *)(void *)ibuf, (unsigned)sizeof(ibuf));
43247561e26Sagc return sizeof(ibuf);
43347561e26Sagc }
43447561e26Sagc
43547561e26Sagc /* hash a string - first length, then string itself */
43647561e26Sagc static int
hash_string(pgp_hash_t * hash,const uint8_t * buf,uint32_t len)437fc1f8641Sagc hash_string(pgp_hash_t *hash, const uint8_t *buf, uint32_t len)
43847561e26Sagc {
439fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
44047561e26Sagc hexdump(stderr, "hash_string", buf, len);
44147561e26Sagc }
44247561e26Sagc hash_uint32(hash, len);
44347561e26Sagc (*hash->add)(hash, buf, len);
44469d4f30fSagc return (int)(sizeof(len) + len);
44547561e26Sagc }
44647561e26Sagc
44747561e26Sagc /* hash a bignum, possibly padded - first length, then string itself */
44847561e26Sagc static int
hash_bignum(pgp_hash_t * hash,BIGNUM * bignum)449fc1f8641Sagc hash_bignum(pgp_hash_t *hash, BIGNUM *bignum)
45047561e26Sagc {
45147561e26Sagc uint8_t *bn;
45247561e26Sagc size_t len;
45347561e26Sagc int padbyte;
45447561e26Sagc
45547561e26Sagc if (BN_is_zero(bignum)) {
45647561e26Sagc hash_uint32(hash, 0);
45747561e26Sagc return sizeof(len);
45847561e26Sagc }
45947561e26Sagc if ((len = (size_t) BN_num_bytes(bignum)) < 1) {
46047561e26Sagc (void) fprintf(stderr, "hash_bignum: bad size\n");
46147561e26Sagc return 0;
46247561e26Sagc }
46347561e26Sagc if ((bn = calloc(1, len)) == NULL) {
46447561e26Sagc (void) fprintf(stderr, "hash_bignum: bad bn alloc\n");
46547561e26Sagc return 0;
46647561e26Sagc }
46747561e26Sagc BN_bn2bin(bignum, bn + 1);
46847561e26Sagc bn[0] = 0x0;
46947561e26Sagc padbyte = (bn[1] & 0x80) ? 1 : 0;
47069d4f30fSagc hash_string(hash, bn + 1 - padbyte, (unsigned)(len + padbyte));
47147561e26Sagc free(bn);
47269d4f30fSagc return (int)(sizeof(len) + len + padbyte);
47347561e26Sagc }
47447561e26Sagc
47593bf6008Sagc /** \file
47693bf6008Sagc */
47793bf6008Sagc
47893bf6008Sagc /**
47993bf6008Sagc * \ingroup Core_Keys
48093bf6008Sagc * \brief Calculate a public key fingerprint.
48193bf6008Sagc * \param fp Where to put the calculated fingerprint
48293bf6008Sagc * \param key The key for which the fingerprint is calculated
48393bf6008Sagc */
48447561e26Sagc int
pgp_fingerprint(pgp_fingerprint_t * fp,const pgp_pubkey_t * key,pgp_hash_alg_t hashtype)485fc1f8641Sagc pgp_fingerprint(pgp_fingerprint_t *fp, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype)
48693bf6008Sagc {
487fc1f8641Sagc pgp_memory_t *mem;
488fc1f8641Sagc pgp_hash_t hash;
48947561e26Sagc const char *type;
49047561e26Sagc uint32_t len;
49193bf6008Sagc
492fc1f8641Sagc mem = pgp_memory_new();
49347561e26Sagc if (key->version == 2 || key->version == 3) {
494fc1f8641Sagc if (key->alg != PGP_PKA_RSA &&
495fc1f8641Sagc key->alg != PGP_PKA_RSA_ENCRYPT_ONLY &&
496fc1f8641Sagc key->alg != PGP_PKA_RSA_SIGN_ONLY) {
497bcfd8565Sagc (void) fprintf(stderr,
498fc1f8641Sagc "pgp_fingerprint: bad algorithm\n");
49947561e26Sagc return 0;
500bcfd8565Sagc }
501fc1f8641Sagc pgp_hash_md5(&hash);
50247561e26Sagc if (!hash.init(&hash)) {
5037affbacaSagc (void) fprintf(stderr,
504fc1f8641Sagc "pgp_fingerprint: bad md5 alloc\n");
50547561e26Sagc return 0;
5067affbacaSagc }
50747561e26Sagc hash_bignum(&hash, key->key.rsa.n);
50847561e26Sagc hash_bignum(&hash, key->key.rsa.e);
50947561e26Sagc fp->length = hash.finish(&hash, fp->fingerprint);
510fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
51147561e26Sagc hexdump(stderr, "v2/v3 fingerprint", fp->fingerprint, fp->length);
51293bf6008Sagc }
513fc1f8641Sagc } else if (hashtype == PGP_HASH_MD5) {
514fc1f8641Sagc pgp_hash_md5(&hash);
51547561e26Sagc if (!hash.init(&hash)) {
51647561e26Sagc (void) fprintf(stderr,
517fc1f8641Sagc "pgp_fingerprint: bad md5 alloc\n");
51847561e26Sagc return 0;
51947561e26Sagc }
520fc1f8641Sagc type = (key->alg == PGP_PKA_RSA) ? "ssh-rsa" : "ssh-dss";
52169d4f30fSagc hash_string(&hash, (const uint8_t *)(const void *)type, (unsigned)strlen(type));
52247561e26Sagc switch(key->alg) {
523fc1f8641Sagc case PGP_PKA_RSA:
52447561e26Sagc hash_bignum(&hash, key->key.rsa.e);
52547561e26Sagc hash_bignum(&hash, key->key.rsa.n);
52647561e26Sagc break;
527fc1f8641Sagc case PGP_PKA_DSA:
52847561e26Sagc hash_bignum(&hash, key->key.dsa.p);
52947561e26Sagc hash_bignum(&hash, key->key.dsa.q);
53047561e26Sagc hash_bignum(&hash, key->key.dsa.g);
53147561e26Sagc hash_bignum(&hash, key->key.dsa.y);
53247561e26Sagc break;
53347561e26Sagc default:
53447561e26Sagc break;
53547561e26Sagc }
53647561e26Sagc fp->length = hash.finish(&hash, fp->fingerprint);
537fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
53847561e26Sagc hexdump(stderr, "md5 fingerprint", fp->fingerprint, fp->length);
53947561e26Sagc }
54047561e26Sagc } else {
541fc1f8641Sagc pgp_build_pubkey(mem, key, 0);
542fc1f8641Sagc pgp_hash_sha1(&hash);
54347561e26Sagc if (!hash.init(&hash)) {
5447affbacaSagc (void) fprintf(stderr,
545fc1f8641Sagc "pgp_fingerprint: bad sha1 alloc\n");
54647561e26Sagc return 0;
5477affbacaSagc }
548fc1f8641Sagc len = (unsigned)pgp_mem_len(mem);
549fc1f8641Sagc pgp_hash_add_int(&hash, 0x99, 1);
550fc1f8641Sagc pgp_hash_add_int(&hash, len, 2);
551fc1f8641Sagc hash.add(&hash, pgp_mem_data(mem), len);
55247561e26Sagc fp->length = hash.finish(&hash, fp->fingerprint);
553fc1f8641Sagc pgp_memory_free(mem);
554fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
55547561e26Sagc hexdump(stderr, "sha1 fingerprint", fp->fingerprint, fp->length);
55693bf6008Sagc }
55793bf6008Sagc }
55847561e26Sagc return 1;
55947561e26Sagc }
56093bf6008Sagc
56193bf6008Sagc /**
56293bf6008Sagc * \ingroup Core_Keys
56393bf6008Sagc * \brief Calculate the Key ID from the public key.
56493bf6008Sagc * \param keyid Space for the calculated ID to be stored
56593bf6008Sagc * \param key The key for which the ID is calculated
56693bf6008Sagc */
56793bf6008Sagc
56847561e26Sagc int
pgp_keyid(uint8_t * keyid,const size_t idlen,const pgp_pubkey_t * key,pgp_hash_alg_t hashtype)569fc1f8641Sagc pgp_keyid(uint8_t *keyid, const size_t idlen, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype)
57093bf6008Sagc {
571fc1f8641Sagc pgp_fingerprint_t finger;
57291c29c74Sagc
57393bf6008Sagc if (key->version == 2 || key->version == 3) {
574814ccb85Sagc unsigned n;
575b15ec256Sagc uint8_t bn[NETPGP_BUFSIZ];
57693bf6008Sagc
577814ccb85Sagc n = (unsigned) BN_num_bytes(key->key.rsa.n);
578bcfd8565Sagc if (n > sizeof(bn)) {
579fc1f8641Sagc (void) fprintf(stderr, "pgp_keyid: bad num bytes\n");
58047561e26Sagc return 0;
581bcfd8565Sagc }
582fc1f8641Sagc if (key->alg != PGP_PKA_RSA &&
583fc1f8641Sagc key->alg != PGP_PKA_RSA_ENCRYPT_ONLY &&
584fc1f8641Sagc key->alg != PGP_PKA_RSA_SIGN_ONLY) {
585fc1f8641Sagc (void) fprintf(stderr, "pgp_keyid: bad algorithm\n");
58647561e26Sagc return 0;
587bcfd8565Sagc }
58893bf6008Sagc BN_bn2bin(key->key.rsa.n, bn);
5899b753456Sagc (void) memcpy(keyid, bn + n - idlen, idlen);
59093bf6008Sagc } else {
591fc1f8641Sagc pgp_fingerprint(&finger, key, hashtype);
59293bf6008Sagc (void) memcpy(keyid,
59393bf6008Sagc finger.fingerprint + finger.length - idlen,
59493bf6008Sagc idlen);
59593bf6008Sagc }
59647561e26Sagc return 1;
59793bf6008Sagc }
59893bf6008Sagc
59993bf6008Sagc /**
60093bf6008Sagc \ingroup Core_Hashes
60193bf6008Sagc \brief Add to the hash
60293bf6008Sagc \param hash Hash to add to
60393bf6008Sagc \param n Int to add
60493bf6008Sagc \param length Length of int in bytes
60593bf6008Sagc */
60693bf6008Sagc void
pgp_hash_add_int(pgp_hash_t * hash,unsigned n,unsigned length)607fc1f8641Sagc pgp_hash_add_int(pgp_hash_t *hash, unsigned n, unsigned length)
60893bf6008Sagc {
609b15ec256Sagc uint8_t c;
61093bf6008Sagc
611b15ec256Sagc while (length--) {
61257324b9fSagc c = n >> (length * 8);
61357324b9fSagc hash->add(hash, &c, 1);
61493bf6008Sagc }
61593bf6008Sagc }
61693bf6008Sagc
61793bf6008Sagc /**
61893bf6008Sagc \ingroup Core_Hashes
61993bf6008Sagc \brief Setup hash for given hash algorithm
62093bf6008Sagc \param hash Hash to set up
62193bf6008Sagc \param alg Hash algorithm to use
62293bf6008Sagc */
62393bf6008Sagc void
pgp_hash_any(pgp_hash_t * hash,pgp_hash_alg_t alg)624fc1f8641Sagc pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg)
62593bf6008Sagc {
62693bf6008Sagc switch (alg) {
627fc1f8641Sagc case PGP_HASH_MD5:
628fc1f8641Sagc pgp_hash_md5(hash);
62993bf6008Sagc break;
63093bf6008Sagc
631fc1f8641Sagc case PGP_HASH_SHA1:
632fc1f8641Sagc pgp_hash_sha1(hash);
63393bf6008Sagc break;
63493bf6008Sagc
635fc1f8641Sagc case PGP_HASH_SHA256:
636fc1f8641Sagc pgp_hash_sha256(hash);
63793bf6008Sagc break;
63893bf6008Sagc
639fc1f8641Sagc case PGP_HASH_SHA384:
640fc1f8641Sagc pgp_hash_sha384(hash);
64193bf6008Sagc break;
64293bf6008Sagc
643fc1f8641Sagc case PGP_HASH_SHA512:
644fc1f8641Sagc pgp_hash_sha512(hash);
64593bf6008Sagc break;
64693bf6008Sagc
647fc1f8641Sagc case PGP_HASH_SHA224:
648fc1f8641Sagc pgp_hash_sha224(hash);
64993bf6008Sagc break;
65093bf6008Sagc
65193bf6008Sagc default:
652fc1f8641Sagc (void) fprintf(stderr, "pgp_hash_any: bad algorithm\n");
65393bf6008Sagc }
65493bf6008Sagc }
65593bf6008Sagc
65693bf6008Sagc /**
65793bf6008Sagc \ingroup Core_Hashes
65893bf6008Sagc \brief Returns size of hash for given hash algorithm
65993bf6008Sagc \param alg Hash algorithm to use
66093bf6008Sagc \return Size of hash algorithm in bytes
66193bf6008Sagc */
66293bf6008Sagc unsigned
pgp_hash_size(pgp_hash_alg_t alg)663fc1f8641Sagc pgp_hash_size(pgp_hash_alg_t alg)
66493bf6008Sagc {
66593bf6008Sagc switch (alg) {
666fc1f8641Sagc case PGP_HASH_MD5:
66793bf6008Sagc return 16;
66893bf6008Sagc
669fc1f8641Sagc case PGP_HASH_SHA1:
67093bf6008Sagc return 20;
67193bf6008Sagc
672fc1f8641Sagc case PGP_HASH_SHA256:
67393bf6008Sagc return 32;
67493bf6008Sagc
675fc1f8641Sagc case PGP_HASH_SHA224:
67693bf6008Sagc return 28;
67793bf6008Sagc
678fc1f8641Sagc case PGP_HASH_SHA512:
67993bf6008Sagc return 64;
68093bf6008Sagc
681fc1f8641Sagc case PGP_HASH_SHA384:
68293bf6008Sagc return 48;
68393bf6008Sagc
68493bf6008Sagc default:
685fc1f8641Sagc (void) fprintf(stderr, "pgp_hash_size: bad algorithm\n");
68693bf6008Sagc }
68793bf6008Sagc
68893bf6008Sagc return 0;
68993bf6008Sagc }
69093bf6008Sagc
69193bf6008Sagc /**
69293bf6008Sagc \ingroup Core_Hashes
69393bf6008Sagc \brief Returns hash enum corresponding to given string
69493bf6008Sagc \param hash Text name of hash algorithm i.e. "SHA1"
695fc1f8641Sagc \returns Corresponding enum i.e. PGP_HASH_SHA1
69693bf6008Sagc */
697fc1f8641Sagc pgp_hash_alg_t
pgp_str_to_hash_alg(const char * hash)698fc1f8641Sagc pgp_str_to_hash_alg(const char *hash)
69993bf6008Sagc {
700b15ec256Sagc if (hash == NULL) {
701fc1f8641Sagc return PGP_DEFAULT_HASH_ALGORITHM;
702b15ec256Sagc }
703b15ec256Sagc if (netpgp_strcasecmp(hash, "SHA1") == 0) {
704fc1f8641Sagc return PGP_HASH_SHA1;
705b1b58706Sagc }
706b15ec256Sagc if (netpgp_strcasecmp(hash, "MD5") == 0) {
707fc1f8641Sagc return PGP_HASH_MD5;
708b1b58706Sagc }
709b15ec256Sagc if (netpgp_strcasecmp(hash, "SHA256") == 0) {
710fc1f8641Sagc return PGP_HASH_SHA256;
711b1b58706Sagc }
71293bf6008Sagc /*
713b15ec256Sagc if (netpgp_strcasecmp(hash,"SHA224") == 0) {
714fc1f8641Sagc return PGP_HASH_SHA224;
715b1b58706Sagc }
71693bf6008Sagc */
717b15ec256Sagc if (netpgp_strcasecmp(hash, "SHA512") == 0) {
718fc1f8641Sagc return PGP_HASH_SHA512;
719b1b58706Sagc }
720b15ec256Sagc if (netpgp_strcasecmp(hash, "SHA384") == 0) {
721fc1f8641Sagc return PGP_HASH_SHA384;
722b1b58706Sagc }
723fc1f8641Sagc return PGP_HASH_UNKNOWN;
72493bf6008Sagc }
72593bf6008Sagc
72693bf6008Sagc /**
72793bf6008Sagc \ingroup Core_Hashes
72893bf6008Sagc \brief Hash given data
72993bf6008Sagc \param out Where to write the hash
73093bf6008Sagc \param alg Hash algorithm to use
73193bf6008Sagc \param in Data to hash
73293bf6008Sagc \param length Length of data
73393bf6008Sagc \return Size of hash created
73493bf6008Sagc */
73593bf6008Sagc unsigned
pgp_hash(uint8_t * out,pgp_hash_alg_t alg,const void * in,size_t length)736fc1f8641Sagc pgp_hash(uint8_t *out, pgp_hash_alg_t alg, const void *in, size_t length)
73793bf6008Sagc {
738fc1f8641Sagc pgp_hash_t hash;
73993bf6008Sagc
740fc1f8641Sagc pgp_hash_any(&hash, alg);
7417affbacaSagc if (!hash.init(&hash)) {
742fc1f8641Sagc (void) fprintf(stderr, "pgp_hash: bad alloc\n");
7437affbacaSagc /* we'll just continue here - don't want to return a 0 hash */
7447affbacaSagc /* XXX - agc - no way to return failure */
7457affbacaSagc }
74669d4f30fSagc hash.add(&hash, in, (unsigned)length);
74793bf6008Sagc return hash.finish(&hash, out);
74893bf6008Sagc }
74993bf6008Sagc
75093bf6008Sagc /**
75193bf6008Sagc \ingroup Core_Hashes
75293bf6008Sagc \brief Calculate hash for MDC packet
75393bf6008Sagc \param preamble Preamble to hash
75493bf6008Sagc \param sz_preamble Size of preamble
75593bf6008Sagc \param plaintext Plaintext to hash
75693bf6008Sagc \param sz_plaintext Size of plaintext
75793bf6008Sagc \param hashed Resulting hash
75893bf6008Sagc */
75993bf6008Sagc void
pgp_calc_mdc_hash(const uint8_t * preamble,const size_t sz_preamble,const uint8_t * plaintext,const unsigned sz_plaintext,uint8_t * hashed)760fc1f8641Sagc pgp_calc_mdc_hash(const uint8_t *preamble,
7612232f800Sagc const size_t sz_preamble,
762b15ec256Sagc const uint8_t *plaintext,
763814ccb85Sagc const unsigned sz_plaintext,
764b15ec256Sagc uint8_t *hashed)
76593bf6008Sagc {
766fc1f8641Sagc pgp_hash_t hash;
767b15ec256Sagc uint8_t c;
76893bf6008Sagc
769fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
77047561e26Sagc hexdump(stderr, "preamble", preamble, sz_preamble);
77147561e26Sagc hexdump(stderr, "plaintext", plaintext, sz_plaintext);
77293bf6008Sagc }
77393bf6008Sagc /* init */
774fc1f8641Sagc pgp_hash_any(&hash, PGP_HASH_SHA1);
7757affbacaSagc if (!hash.init(&hash)) {
776fc1f8641Sagc (void) fprintf(stderr, "pgp_calc_mdc_hash: bad alloc\n");
7777affbacaSagc /* we'll just continue here - it will die anyway */
7787affbacaSagc /* agc - XXX - no way to return failure */
7797affbacaSagc }
78093bf6008Sagc
78193bf6008Sagc /* preamble */
78269d4f30fSagc hash.add(&hash, preamble, (unsigned)sz_preamble);
78393bf6008Sagc /* plaintext */
78493bf6008Sagc hash.add(&hash, plaintext, sz_plaintext);
78593bf6008Sagc /* MDC packet tag */
7860df5e957Sagc c = MDC_PKT_TAG;
78757324b9fSagc hash.add(&hash, &c, 1);
78893bf6008Sagc /* MDC packet len */
789fc1f8641Sagc c = PGP_SHA1_HASH_SIZE;
79057324b9fSagc hash.add(&hash, &c, 1);
79193bf6008Sagc
79293bf6008Sagc /* finish */
79393bf6008Sagc hash.finish(&hash, hashed);
79493bf6008Sagc
795fc1f8641Sagc if (pgp_get_debug_level(__FILE__)) {
796fc1f8641Sagc hexdump(stderr, "hashed", hashed, PGP_SHA1_HASH_SIZE);
79793bf6008Sagc }
79893bf6008Sagc }
79993bf6008Sagc
80093bf6008Sagc /**
80193bf6008Sagc \ingroup HighLevel_Supported
80293bf6008Sagc \brief Is this Hash Algorithm supported?
80393bf6008Sagc \param hash_alg Hash Algorithm to check
8044b3a3e18Sagc \return 1 if supported; else 0
80593bf6008Sagc */
8064b3a3e18Sagc unsigned
pgp_is_hash_alg_supported(const pgp_hash_alg_t * hash_alg)807fc1f8641Sagc pgp_is_hash_alg_supported(const pgp_hash_alg_t *hash_alg)
80893bf6008Sagc {
80993bf6008Sagc switch (*hash_alg) {
810fc1f8641Sagc case PGP_HASH_MD5:
811fc1f8641Sagc case PGP_HASH_SHA1:
812fc1f8641Sagc case PGP_HASH_SHA256:
8134b3a3e18Sagc return 1;
81493bf6008Sagc
81593bf6008Sagc default:
8164b3a3e18Sagc return 0;
81793bf6008Sagc }
81893bf6008Sagc }
81993bf6008Sagc
8203dc7aea1Sagc /* structure to map string to cipher def */
8213dc7aea1Sagc typedef struct str2cipher_t {
8223dc7aea1Sagc const char *s; /* cipher name */
823fc1f8641Sagc pgp_symm_alg_t i; /* cipher def */
8243dc7aea1Sagc } str2cipher_t;
8253dc7aea1Sagc
8263dc7aea1Sagc static str2cipher_t str2cipher[] = {
827fc1f8641Sagc { "cast5", PGP_SA_CAST5 },
828fc1f8641Sagc { "idea", PGP_SA_IDEA },
829fc1f8641Sagc { "aes128", PGP_SA_AES_128 },
830fc1f8641Sagc { "aes256", PGP_SA_AES_256 },
8313fba244aSjhigh { "blowfish", PGP_SA_BLOWFISH },
832fc1f8641Sagc { "camellia128", PGP_SA_CAMELLIA_128 },
833fc1f8641Sagc { "camellia256", PGP_SA_CAMELLIA_256 },
834fc1f8641Sagc { "tripledes", PGP_SA_TRIPLEDES },
8353dc7aea1Sagc { NULL, 0 }
8363dc7aea1Sagc };
8373dc7aea1Sagc
8383dc7aea1Sagc /* convert from a string to a cipher definition */
839fc1f8641Sagc pgp_symm_alg_t
pgp_str_to_cipher(const char * cipher)840fc1f8641Sagc pgp_str_to_cipher(const char *cipher)
8413dc7aea1Sagc {
8423dc7aea1Sagc str2cipher_t *sp;
8433dc7aea1Sagc
8443dc7aea1Sagc for (sp = str2cipher ; cipher && sp->s ; sp++) {
8453dc7aea1Sagc if (netpgp_strcasecmp(cipher, sp->s) == 0) {
8463dc7aea1Sagc return sp->i;
8473dc7aea1Sagc }
8483dc7aea1Sagc }
849fc1f8641Sagc return PGP_SA_DEFAULT_CIPHER;
8503dc7aea1Sagc }
8513dc7aea1Sagc
85293bf6008Sagc void
pgp_random(void * dest,size_t length)853fc1f8641Sagc pgp_random(void *dest, size_t length)
85493bf6008Sagc {
855efdd9dbaSagc RAND_bytes(dest, (int)length);
85693bf6008Sagc }
85793bf6008Sagc
85893bf6008Sagc /**
85993bf6008Sagc \ingroup HighLevel_Memory
86093bf6008Sagc \brief Memory to initialise
86193bf6008Sagc \param mem memory to initialise
86293bf6008Sagc \param needed Size to initialise to
86393bf6008Sagc */
86493bf6008Sagc void
pgp_memory_init(pgp_memory_t * mem,size_t needed)865fc1f8641Sagc pgp_memory_init(pgp_memory_t *mem, size_t needed)
86693bf6008Sagc {
867b15ec256Sagc uint8_t *temp;
8687affbacaSagc
86993bf6008Sagc mem->length = 0;
87093bf6008Sagc if (mem->buf) {
87193bf6008Sagc if (mem->allocated < needed) {
8727affbacaSagc if ((temp = realloc(mem->buf, needed)) == NULL) {
873fc1f8641Sagc (void) fprintf(stderr, "pgp_memory_init: bad alloc\n");
8747affbacaSagc } else {
8757affbacaSagc mem->buf = temp;
87693bf6008Sagc mem->allocated = needed;
87793bf6008Sagc }
87893bf6008Sagc }
8797affbacaSagc } else {
8807affbacaSagc if ((mem->buf = calloc(1, needed)) == NULL) {
881fc1f8641Sagc (void) fprintf(stderr, "pgp_memory_init: bad alloc\n");
8827affbacaSagc } else {
88393bf6008Sagc mem->allocated = needed;
88493bf6008Sagc }
8857affbacaSagc }
8867affbacaSagc }
88793bf6008Sagc
88893bf6008Sagc /**
88993bf6008Sagc \ingroup HighLevel_Memory
89093bf6008Sagc \brief Pad memory to required length
89193bf6008Sagc \param mem Memory to use
89293bf6008Sagc \param length New size
89393bf6008Sagc */
89493bf6008Sagc void
pgp_memory_pad(pgp_memory_t * mem,size_t length)895fc1f8641Sagc pgp_memory_pad(pgp_memory_t *mem, size_t length)
89693bf6008Sagc {
897b15ec256Sagc uint8_t *temp;
8980aa9bccaSagc
899bcfd8565Sagc if (mem->allocated < mem->length) {
900fc1f8641Sagc (void) fprintf(stderr, "pgp_memory_pad: bad alloc in\n");
901bcfd8565Sagc return;
902bcfd8565Sagc }
90393bf6008Sagc if (mem->allocated < mem->length + length) {
90493bf6008Sagc mem->allocated = mem->allocated * 2 + length;
9050aa9bccaSagc temp = realloc(mem->buf, mem->allocated);
9060aa9bccaSagc if (temp == NULL) {
907fc1f8641Sagc (void) fprintf(stderr, "pgp_memory_pad: bad alloc\n");
9080aa9bccaSagc } else {
9090aa9bccaSagc mem->buf = temp;
9100aa9bccaSagc }
91193bf6008Sagc }
912bcfd8565Sagc if (mem->allocated < mem->length + length) {
913fc1f8641Sagc (void) fprintf(stderr, "pgp_memory_pad: bad alloc out\n");
914bcfd8565Sagc }
91593bf6008Sagc }
91693bf6008Sagc
91793bf6008Sagc /**
91893bf6008Sagc \ingroup HighLevel_Memory
91993bf6008Sagc \brief Add data to memory
92093bf6008Sagc \param mem Memory to which to add
92193bf6008Sagc \param src Data to add
92293bf6008Sagc \param length Length of data to add
92393bf6008Sagc */
92493bf6008Sagc void
pgp_memory_add(pgp_memory_t * mem,const uint8_t * src,size_t length)925fc1f8641Sagc pgp_memory_add(pgp_memory_t *mem, const uint8_t *src, size_t length)
92693bf6008Sagc {
927fc1f8641Sagc pgp_memory_pad(mem, length);
92893bf6008Sagc (void) memcpy(mem->buf + mem->length, src, length);
92993bf6008Sagc mem->length += length;
93093bf6008Sagc }
93193bf6008Sagc
93293bf6008Sagc /* XXX: this could be refactored via the writer, but an awful lot of */
93393bf6008Sagc /* hoops to jump through for 2 lines of code! */
93493bf6008Sagc void
pgp_memory_place_int(pgp_memory_t * mem,unsigned offset,unsigned n,size_t length)935fc1f8641Sagc pgp_memory_place_int(pgp_memory_t *mem, unsigned offset, unsigned n,
93693bf6008Sagc size_t length)
93793bf6008Sagc {
938bcfd8565Sagc if (mem->allocated < offset + length) {
939bcfd8565Sagc (void) fprintf(stderr,
940fc1f8641Sagc "pgp_memory_place_int: bad alloc\n");
941bcfd8565Sagc } else {
9422232f800Sagc while (length-- > 0) {
94393bf6008Sagc mem->buf[offset++] = n >> (length * 8);
94493bf6008Sagc }
945bcfd8565Sagc }
946bcfd8565Sagc }
94793bf6008Sagc
94893bf6008Sagc /**
94993bf6008Sagc * \ingroup HighLevel_Memory
95093bf6008Sagc * \brief Retains allocated memory and set length of stored data to zero.
95193bf6008Sagc * \param mem Memory to clear
952fc1f8641Sagc * \sa pgp_memory_release()
953fc1f8641Sagc * \sa pgp_memory_free()
95493bf6008Sagc */
95593bf6008Sagc void
pgp_memory_clear(pgp_memory_t * mem)956fc1f8641Sagc pgp_memory_clear(pgp_memory_t *mem)
95793bf6008Sagc {
95893bf6008Sagc mem->length = 0;
95993bf6008Sagc }
96093bf6008Sagc
96193bf6008Sagc /**
96293bf6008Sagc \ingroup HighLevel_Memory
96393bf6008Sagc \brief Free memory and associated data
96493bf6008Sagc \param mem Memory to free
96593bf6008Sagc \note This does not free mem itself
966fc1f8641Sagc \sa pgp_memory_clear()
967fc1f8641Sagc \sa pgp_memory_free()
96893bf6008Sagc */
96993bf6008Sagc void
pgp_memory_release(pgp_memory_t * mem)970fc1f8641Sagc pgp_memory_release(pgp_memory_t *mem)
97193bf6008Sagc {
9720df5e957Sagc if (mem->mmapped) {
9730df5e957Sagc (void) munmap(mem->buf, mem->length);
9740df5e957Sagc } else {
975814ccb85Sagc free(mem->buf);
9760df5e957Sagc }
97793bf6008Sagc mem->buf = NULL;
97893bf6008Sagc mem->length = 0;
97993bf6008Sagc }
98093bf6008Sagc
98193bf6008Sagc void
pgp_memory_make_packet(pgp_memory_t * out,pgp_content_enum tag)982fc1f8641Sagc pgp_memory_make_packet(pgp_memory_t *out, pgp_content_enum tag)
98393bf6008Sagc {
98493bf6008Sagc size_t extra;
98593bf6008Sagc
9862232f800Sagc extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5;
987fc1f8641Sagc pgp_memory_pad(out, extra + 1);
98893bf6008Sagc memmove(out->buf + extra + 1, out->buf, out->length);
98993bf6008Sagc
990fc1f8641Sagc out->buf[0] = PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT | tag;
99193bf6008Sagc
9922232f800Sagc if (out->length < 192) {
99369d4f30fSagc out->buf[1] = (uint8_t)out->length;
9942232f800Sagc } else if (out->length < 8192 + 192) {
99569d4f30fSagc out->buf[1] = (uint8_t)((out->length - 192) >> 8) + 192;
99669d4f30fSagc out->buf[2] = (uint8_t)(out->length - 192);
99793bf6008Sagc } else {
99893bf6008Sagc out->buf[1] = 0xff;
99969d4f30fSagc out->buf[2] = (uint8_t)(out->length >> 24);
100069d4f30fSagc out->buf[3] = (uint8_t)(out->length >> 16);
100169d4f30fSagc out->buf[4] = (uint8_t)(out->length >> 8);
100269d4f30fSagc out->buf[5] = (uint8_t)(out->length);
100393bf6008Sagc }
100493bf6008Sagc
100593bf6008Sagc out->length += extra + 1;
100693bf6008Sagc }
100793bf6008Sagc
100893bf6008Sagc /**
100993bf6008Sagc \ingroup HighLevel_Memory
1010fc1f8641Sagc \brief Create a new zeroed pgp_memory_t
1011fc1f8641Sagc \return Pointer to new pgp_memory_t
1012fc1f8641Sagc \note Free using pgp_memory_free() after use.
1013fc1f8641Sagc \sa pgp_memory_free()
101493bf6008Sagc */
101593bf6008Sagc
1016fc1f8641Sagc pgp_memory_t *
pgp_memory_new(void)1017fc1f8641Sagc pgp_memory_new(void)
101893bf6008Sagc {
1019fc1f8641Sagc return calloc(1, sizeof(pgp_memory_t));
102093bf6008Sagc }
102193bf6008Sagc
102293bf6008Sagc /**
102393bf6008Sagc \ingroup HighLevel_Memory
102493bf6008Sagc \brief Free memory ptr and associated memory
102593bf6008Sagc \param mem Memory to be freed
1026fc1f8641Sagc \sa pgp_memory_release()
1027fc1f8641Sagc \sa pgp_memory_clear()
102893bf6008Sagc */
102993bf6008Sagc
103093bf6008Sagc void
pgp_memory_free(pgp_memory_t * mem)1031fc1f8641Sagc pgp_memory_free(pgp_memory_t *mem)
103293bf6008Sagc {
1033fc1f8641Sagc pgp_memory_release(mem);
1034814ccb85Sagc free(mem);
103593bf6008Sagc }
103693bf6008Sagc
103793bf6008Sagc /**
103893bf6008Sagc \ingroup HighLevel_Memory
1039fc1f8641Sagc \brief Get length of data stored in pgp_memory_t struct
104093bf6008Sagc \return Number of bytes in data
104193bf6008Sagc */
104293bf6008Sagc size_t
pgp_mem_len(const pgp_memory_t * mem)1043fc1f8641Sagc pgp_mem_len(const pgp_memory_t *mem)
104493bf6008Sagc {
104593bf6008Sagc return mem->length;
104693bf6008Sagc }
104793bf6008Sagc
104893bf6008Sagc /**
104993bf6008Sagc \ingroup HighLevel_Memory
1050fc1f8641Sagc \brief Get data stored in pgp_memory_t struct
105193bf6008Sagc \return Pointer to data
105293bf6008Sagc */
105393bf6008Sagc void *
pgp_mem_data(pgp_memory_t * mem)1054fc1f8641Sagc pgp_mem_data(pgp_memory_t *mem)
105593bf6008Sagc {
105693bf6008Sagc return mem->buf;
105793bf6008Sagc }
105893bf6008Sagc
1059fc1f8641Sagc /* read a gile into an pgp_memory_t */
10600df5e957Sagc int
pgp_mem_readfile(pgp_memory_t * mem,const char * f)1061fc1f8641Sagc pgp_mem_readfile(pgp_memory_t *mem, const char *f)
10620df5e957Sagc {
10630df5e957Sagc struct stat st;
10640df5e957Sagc FILE *fp;
10650df5e957Sagc int cc;
10660df5e957Sagc
10670df5e957Sagc if ((fp = fopen(f, "rb")) == NULL) {
10680df5e957Sagc (void) fprintf(stderr,
1069fc1f8641Sagc "pgp_mem_readfile: can't open \"%s\"\n", f);
10700df5e957Sagc return 0;
10710df5e957Sagc }
10720df5e957Sagc (void) fstat(fileno(fp), &st);
10730df5e957Sagc mem->allocated = (size_t)st.st_size;
10740df5e957Sagc mem->buf = mmap(NULL, mem->allocated, PROT_READ,
1075814ccb85Sagc MAP_PRIVATE | MAP_FILE, fileno(fp), 0);
10760df5e957Sagc if (mem->buf == MAP_FAILED) {
10770df5e957Sagc /* mmap failed for some reason - try to allocate memory */
10780df5e957Sagc if ((mem->buf = calloc(1, mem->allocated)) == NULL) {
1079fc1f8641Sagc (void) fprintf(stderr, "pgp_mem_readfile: calloc\n");
10800df5e957Sagc (void) fclose(fp);
10810df5e957Sagc return 0;
10820df5e957Sagc }
10830df5e957Sagc /* read into contents of mem */
10840df5e957Sagc for (mem->length = 0 ;
1085593d671cSagc (cc = (int)read(fileno(fp), &mem->buf[mem->length],
108669d4f30fSagc (size_t)(mem->allocated - mem->length))) > 0 ;
10870df5e957Sagc mem->length += (size_t)cc) {
10880df5e957Sagc }
10890df5e957Sagc } else {
10900df5e957Sagc mem->length = mem->allocated;
10910df5e957Sagc mem->mmapped = 1;
10920df5e957Sagc }
10930df5e957Sagc (void) fclose(fp);
10940df5e957Sagc return (mem->allocated == mem->length);
10950df5e957Sagc }
10960df5e957Sagc
109793bf6008Sagc typedef struct {
1098b15ec256Sagc uint16_t sum;
109993bf6008Sagc } sum16_t;
110093bf6008Sagc
110193bf6008Sagc
110293bf6008Sagc /**
110393bf6008Sagc * Searches the given map for the given type.
110493bf6008Sagc * Returns a human-readable descriptive string if found,
110593bf6008Sagc * returns NULL if not found
110693bf6008Sagc *
110793bf6008Sagc * It is the responsibility of the calling function to handle the
110893bf6008Sagc * error case sensibly (i.e. don't just print out the return string.
110993bf6008Sagc *
111093bf6008Sagc */
111193bf6008Sagc static const char *
str_from_map_or_null(int type,pgp_map_t * map)1112fc1f8641Sagc str_from_map_or_null(int type, pgp_map_t *map)
111393bf6008Sagc {
1114fc1f8641Sagc pgp_map_t *row;
111593bf6008Sagc
111693bf6008Sagc for (row = map; row->string != NULL; row++) {
111793bf6008Sagc if (row->type == type) {
111893bf6008Sagc return row->string;
111993bf6008Sagc }
112093bf6008Sagc }
112193bf6008Sagc return NULL;
112293bf6008Sagc }
112393bf6008Sagc
112493bf6008Sagc /**
112593bf6008Sagc * \ingroup Core_Print
112693bf6008Sagc *
112793bf6008Sagc * Searches the given map for the given type.
112893bf6008Sagc * Returns a readable string if found, "Unknown" if not.
112993bf6008Sagc */
113093bf6008Sagc
113193bf6008Sagc const char *
pgp_str_from_map(int type,pgp_map_t * map)1132fc1f8641Sagc pgp_str_from_map(int type, pgp_map_t *map)
113393bf6008Sagc {
113493bf6008Sagc const char *str;
113593bf6008Sagc
113693bf6008Sagc str = str_from_map_or_null(type, map);
113793bf6008Sagc return (str) ? str : "Unknown";
113893bf6008Sagc }
113993bf6008Sagc
114047561e26Sagc #define LINELEN 16
114193bf6008Sagc
114247561e26Sagc /* show hexadecimal/ascii dump */
114347561e26Sagc void
hexdump(FILE * fp,const char * header,const uint8_t * src,size_t length)114447561e26Sagc hexdump(FILE *fp, const char *header, const uint8_t *src, size_t length)
114547561e26Sagc {
114647561e26Sagc size_t i;
114747561e26Sagc char line[LINELEN + 1];
114847561e26Sagc
114947561e26Sagc (void) fprintf(fp, "%s%s", (header) ? header : "", (header) ? "\n" : "");
1150ad39646bSagc (void) fprintf(fp, "[%" PRIsize "u char%s]\n", length, (length == 1) ? "" : "s");
115147561e26Sagc for (i = 0 ; i < length ; i++) {
115247561e26Sagc if (i % LINELEN == 0) {
1153ad39646bSagc (void) fprintf(fp, "%.5" PRIsize "u | ", i);
115447561e26Sagc }
115547561e26Sagc (void) fprintf(fp, "%.02x ", (uint8_t)src[i]);
115647561e26Sagc line[i % LINELEN] = (isprint(src[i])) ? src[i] : '.';
115747561e26Sagc if (i % LINELEN == LINELEN - 1) {
115847561e26Sagc line[LINELEN] = 0x0;
115947561e26Sagc (void) fprintf(fp, " | %s\n", line);
116047561e26Sagc }
116147561e26Sagc }
116247561e26Sagc if (i % LINELEN != 0) {
116347561e26Sagc for ( ; i % LINELEN != 0 ; i++) {
116447561e26Sagc (void) fprintf(fp, " ");
116547561e26Sagc line[i % LINELEN] = ' ';
116647561e26Sagc }
116747561e26Sagc line[LINELEN] = 0x0;
116847561e26Sagc (void) fprintf(fp, " | %s\n", line);
116993bf6008Sagc }
117093bf6008Sagc }
117193bf6008Sagc
117293bf6008Sagc /**
117393bf6008Sagc * \ingroup HighLevel_Functions
117493bf6008Sagc * \brief Closes down OpenPGP::SDK.
117593bf6008Sagc *
117693bf6008Sagc * Close down OpenPGP:SDK, release any resources under the control of
1177651dd288Sagc * the library.
117893bf6008Sagc */
117993bf6008Sagc
118093bf6008Sagc void
pgp_finish(void)1181fc1f8641Sagc pgp_finish(void)
118293bf6008Sagc {
1183fc1f8641Sagc pgp_crypto_finish();
118493bf6008Sagc }
118593bf6008Sagc
118693bf6008Sagc static int
sum16_reader(pgp_stream_t * stream,void * dest_,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)1187b0df0a22Sagc sum16_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors,
1188fc1f8641Sagc pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
118993bf6008Sagc {
1190b15ec256Sagc const uint8_t *dest = dest_;
1191fc1f8641Sagc sum16_t *arg = pgp_reader_get_arg(readinfo);
11922232f800Sagc int r;
119393bf6008Sagc int n;
119493bf6008Sagc
1195b0df0a22Sagc r = pgp_stacked_read(stream, dest_, length, errors, readinfo, cbinfo);
119693bf6008Sagc if (r < 0) {
119793bf6008Sagc return r;
119893bf6008Sagc }
119993bf6008Sagc for (n = 0; n < r; ++n) {
120093bf6008Sagc arg->sum = (arg->sum + dest[n]) & 0xffff;
120193bf6008Sagc }
120293bf6008Sagc return r;
120393bf6008Sagc }
120493bf6008Sagc
120593bf6008Sagc static void
sum16_destroyer(pgp_reader_t * readinfo)1206fc1f8641Sagc sum16_destroyer(pgp_reader_t *readinfo)
120793bf6008Sagc {
1208fc1f8641Sagc free(pgp_reader_get_arg(readinfo));
120993bf6008Sagc }
121093bf6008Sagc
121193bf6008Sagc /**
121293bf6008Sagc \ingroup Internal_Readers_Sum16
121341335e2dSagc \param stream Parse settings
121493bf6008Sagc */
121593bf6008Sagc
121693bf6008Sagc void
pgp_reader_push_sum16(pgp_stream_t * stream)1217fc1f8641Sagc pgp_reader_push_sum16(pgp_stream_t *stream)
121893bf6008Sagc {
12197affbacaSagc sum16_t *arg;
122093bf6008Sagc
12217affbacaSagc if ((arg = calloc(1, sizeof(*arg))) == NULL) {
1222fc1f8641Sagc (void) fprintf(stderr, "pgp_reader_push_sum16: bad alloc\n");
12237affbacaSagc } else {
1224fc1f8641Sagc pgp_reader_push(stream, sum16_reader, sum16_destroyer, arg);
122593bf6008Sagc }
12267affbacaSagc }
122793bf6008Sagc
122893bf6008Sagc /**
122993bf6008Sagc \ingroup Internal_Readers_Sum16
123041335e2dSagc \param stream Parse settings
123193bf6008Sagc \return sum
123293bf6008Sagc */
1233b15ec256Sagc uint16_t
pgp_reader_pop_sum16(pgp_stream_t * stream)1234fc1f8641Sagc pgp_reader_pop_sum16(pgp_stream_t *stream)
123593bf6008Sagc {
1236b15ec256Sagc uint16_t sum;
12374b3a3e18Sagc sum16_t *arg;
123893bf6008Sagc
1239fc1f8641Sagc arg = pgp_reader_get_arg(pgp_readinfo(stream));
12404b3a3e18Sagc sum = arg->sum;
1241fc1f8641Sagc pgp_reader_pop(stream);
124293bf6008Sagc free(arg);
124393bf6008Sagc return sum;
124493bf6008Sagc }
124593bf6008Sagc
124693bf6008Sagc /* small useful functions for setting the file-level debugging levels */
124793bf6008Sagc /* if the debugv list contains the filename in question, we're debugging it */
124893bf6008Sagc
124993bf6008Sagc enum {
125093bf6008Sagc MAX_DEBUG_NAMES = 32
125193bf6008Sagc };
125293bf6008Sagc
125393bf6008Sagc static int debugc;
125493bf6008Sagc static char *debugv[MAX_DEBUG_NAMES];
125593bf6008Sagc
125693bf6008Sagc /* set the debugging level per filename */
125793bf6008Sagc int
pgp_set_debug_level(const char * f)1258fc1f8641Sagc pgp_set_debug_level(const char *f)
125993bf6008Sagc {
126093bf6008Sagc const char *name;
126193bf6008Sagc int i;
126293bf6008Sagc
126393bf6008Sagc if (f == NULL) {
126493bf6008Sagc f = "all";
126593bf6008Sagc }
126693bf6008Sagc if ((name = strrchr(f, '/')) == NULL) {
126793bf6008Sagc name = f;
126893bf6008Sagc } else {
126993bf6008Sagc name += 1;
127093bf6008Sagc }
127193bf6008Sagc for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) {
127293bf6008Sagc if (strcmp(debugv[i], name) == 0) {
127393bf6008Sagc return 1;
127493bf6008Sagc }
127593bf6008Sagc }
127693bf6008Sagc if (i == MAX_DEBUG_NAMES) {
127793bf6008Sagc return 0;
127893bf6008Sagc }
1279b15ec256Sagc debugv[debugc++] = netpgp_strdup(name);
128093bf6008Sagc return 1;
128193bf6008Sagc }
128293bf6008Sagc
128393bf6008Sagc /* get the debugging level per filename */
128493bf6008Sagc int
pgp_get_debug_level(const char * f)1285fc1f8641Sagc pgp_get_debug_level(const char *f)
128693bf6008Sagc {
128793bf6008Sagc const char *name;
128893bf6008Sagc int i;
128993bf6008Sagc
129093bf6008Sagc if ((name = strrchr(f, '/')) == NULL) {
129193bf6008Sagc name = f;
129293bf6008Sagc } else {
129393bf6008Sagc name += 1;
129493bf6008Sagc }
129593bf6008Sagc for (i = 0; i < debugc; i++) {
129693bf6008Sagc if (strcmp(debugv[i], "all") == 0 ||
129793bf6008Sagc strcmp(debugv[i], name) == 0) {
129893bf6008Sagc return 1;
129993bf6008Sagc }
130093bf6008Sagc }
130193bf6008Sagc return 0;
130293bf6008Sagc }
130393bf6008Sagc
130493bf6008Sagc /* return the version for the library */
130593bf6008Sagc const char *
pgp_get_info(const char * type)1306fc1f8641Sagc pgp_get_info(const char *type)
130793bf6008Sagc {
130893bf6008Sagc if (strcmp(type, "version") == 0) {
130993bf6008Sagc return NETPGP_VERSION_STRING;
131093bf6008Sagc }
131193bf6008Sagc if (strcmp(type, "maintainer") == 0) {
131293bf6008Sagc return NETPGP_MAINTAINER;
131393bf6008Sagc }
131493bf6008Sagc return "[unknown]";
131593bf6008Sagc }
1316d21b929eSagc
13179e63cf3fSagc /* local version of asprintf so we don't have to play autoconf games */
13189e63cf3fSagc int
pgp_asprintf(char ** ret,const char * fmt,...)1319fc1f8641Sagc pgp_asprintf(char **ret, const char *fmt, ...)
13209e63cf3fSagc {
13219e63cf3fSagc va_list args;
13229e63cf3fSagc char buf[120 * 1024]; /* XXX - "huge" buffer on stack */
13239e63cf3fSagc int cc;
13249e63cf3fSagc
13259e63cf3fSagc va_start(args, fmt);
13269e63cf3fSagc cc = vsnprintf(buf, sizeof(buf), fmt, args);
13279e63cf3fSagc va_end(args);
13289e63cf3fSagc if ((*ret = calloc(1, (size_t)(cc + 1))) == NULL) {
13299e63cf3fSagc *ret = NULL;
13309e63cf3fSagc return -1;
13319e63cf3fSagc }
13329e63cf3fSagc (void) memcpy(*ret, buf, (size_t)cc);
13339e63cf3fSagc (*ret)[cc] = 0x0;
13349e63cf3fSagc return cc;
13359e63cf3fSagc }
13369e63cf3fSagc
1337d21b929eSagc void
netpgp_log(const char * fmt,...)1338d21b929eSagc netpgp_log(const char *fmt, ...)
1339d21b929eSagc {
1340d21b929eSagc va_list vp;
1341d21b929eSagc time_t t;
1342d21b929eSagc char buf[BUFSIZ * 2];
1343d21b929eSagc int cc;
1344d21b929eSagc
1345d21b929eSagc (void) time(&t);
13464167ec87Schristos cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", ctime(&t));
1347d21b929eSagc va_start(vp, fmt);
1348814ccb85Sagc (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp);
1349d21b929eSagc va_end(vp);
1350d21b929eSagc /* do something with message */
1351d21b929eSagc /* put into log buffer? */
1352d21b929eSagc }
1353b15ec256Sagc
1354b15ec256Sagc /* portable replacement for strdup(3) */
1355b15ec256Sagc char *
netpgp_strdup(const char * s)1356b15ec256Sagc netpgp_strdup(const char *s)
1357b15ec256Sagc {
1358b15ec256Sagc size_t len;
1359b15ec256Sagc char *cp;
1360b15ec256Sagc
1361b15ec256Sagc len = strlen(s);
1362b15ec256Sagc if ((cp = calloc(1, len + 1)) != NULL) {
1363b15ec256Sagc (void) memcpy(cp, s, len);
1364b15ec256Sagc cp[len] = 0x0;
1365b15ec256Sagc }
1366b15ec256Sagc return cp;
1367b15ec256Sagc }
1368b15ec256Sagc
1369b15ec256Sagc /* portable replacement for strcasecmp(3) */
1370b15ec256Sagc int
netpgp_strcasecmp(const char * s1,const char * s2)1371b15ec256Sagc netpgp_strcasecmp(const char *s1, const char *s2)
1372b15ec256Sagc {
1373b15ec256Sagc int n;
1374b15ec256Sagc
1375fdfbba49Sagc for (n = 0 ; *s1 && *s2 && (n = tolower((uint8_t)*s1) - tolower((uint8_t)*s2)) == 0 ; s1++, s2++) {
1376b15ec256Sagc }
1377b15ec256Sagc return n;
1378b15ec256Sagc }
1379*0294a66bSjhigh
1380*0294a66bSjhigh int
ecdsa_nid(const pgp_ecdsa_pubkey_t * pub)1381*0294a66bSjhigh ecdsa_nid(const pgp_ecdsa_pubkey_t * pub)
1382*0294a66bSjhigh {
1383*0294a66bSjhigh int i;
1384*0294a66bSjhigh
1385*0294a66bSjhigh for (i = 0; ecdsa_map[i].sname; i++ ) {
1386*0294a66bSjhigh if (pub->len == ecdsa_map[i].len) {
1387*0294a66bSjhigh if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) {
1388*0294a66bSjhigh return ecdsa_map[i].nid;
1389*0294a66bSjhigh }
1390*0294a66bSjhigh }
1391*0294a66bSjhigh }
1392*0294a66bSjhigh return -1;
1393*0294a66bSjhigh }
1394*0294a66bSjhigh
1395*0294a66bSjhigh int
ecdsa_numbits(const pgp_ecdsa_pubkey_t * pub)1396*0294a66bSjhigh ecdsa_numbits(const pgp_ecdsa_pubkey_t * pub)
1397*0294a66bSjhigh {
1398*0294a66bSjhigh int i;
1399*0294a66bSjhigh
1400*0294a66bSjhigh for (i = 0; ecdsa_map[i].sname; i++ ) {
1401*0294a66bSjhigh if (pub->len == ecdsa_map[i].len) {
1402*0294a66bSjhigh if (memcmp(pub->oid, ecdsa_map[i].oid, pub->len) == 0) {
1403*0294a66bSjhigh return ecdsa_map[i].bits;
1404*0294a66bSjhigh }
1405*0294a66bSjhigh }
1406*0294a66bSjhigh }
1407*0294a66bSjhigh return -1;
1408*0294a66bSjhigh }
1409*0294a66bSjhigh
1410*0294a66bSjhigh int
ecdsa_hashsize(const pgp_ecdsa_pubkey_t * pub)1411*0294a66bSjhigh ecdsa_hashsize(const pgp_ecdsa_pubkey_t * pub)
1412*0294a66bSjhigh {
1413*0294a66bSjhigh int bits;
1414*0294a66bSjhigh
1415*0294a66bSjhigh bits = ecdsa_numbits(pub);
1416*0294a66bSjhigh
1417*0294a66bSjhigh if (bits == -1) {
1418*0294a66bSjhigh return -1;
1419*0294a66bSjhigh }
1420*0294a66bSjhigh
1421*0294a66bSjhigh return (bits/8) - (bits%8);
1422*0294a66bSjhigh }
1423*0294a66bSjhigh
1424*0294a66bSjhigh pgp_hash_alg_t
ecdsa_hashalg(const pgp_ecdsa_pubkey_t * pub)1425*0294a66bSjhigh ecdsa_hashalg(const pgp_ecdsa_pubkey_t * pub)
1426*0294a66bSjhigh {
1427*0294a66bSjhigh int nid;
1428*0294a66bSjhigh
1429*0294a66bSjhigh if (pub == NULL) {
1430*0294a66bSjhigh return PGP_HASH_UNKNOWN;
1431*0294a66bSjhigh }
1432*0294a66bSjhigh
1433*0294a66bSjhigh nid = ecdsa_nid(pub);
1434*0294a66bSjhigh
1435*0294a66bSjhigh switch (nid) {
1436*0294a66bSjhigh case NID_X9_62_prime256v1:
1437*0294a66bSjhigh return PGP_HASH_SHA256;
1438*0294a66bSjhigh
1439*0294a66bSjhigh case NID_secp384r1:
1440*0294a66bSjhigh return PGP_HASH_SHA384;
1441*0294a66bSjhigh
1442*0294a66bSjhigh case NID_secp521r1:
1443*0294a66bSjhigh return PGP_HASH_SHA512;
1444*0294a66bSjhigh
1445*0294a66bSjhigh default:
1446*0294a66bSjhigh (void) fprintf(stderr, "ecdsa_hashalg: unknown NID\n");
1447*0294a66bSjhigh }
1448*0294a66bSjhigh
1449*0294a66bSjhigh return PGP_HASH_UNKNOWN;
1450*0294a66bSjhigh }
1451