1*99fc1771Stb /* $OpenBSD: key.c,v 1.27 2021/10/13 16:57:43 tb Exp $ */
2b474cdc2Sangelos /*
3b474cdc2Sangelos * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
4b474cdc2Sangelos *
52edf96f1Sangelos * Copyright (c) 2000-2001 Angelos D. Keromytis.
6b474cdc2Sangelos *
72edf96f1Sangelos * Permission to use, copy, and modify this software with or without fee
8b474cdc2Sangelos * is hereby granted, provided that this entire notice is included in
9b474cdc2Sangelos * all copies of any software which is or includes a copy or
10b474cdc2Sangelos * modification of this software.
11b474cdc2Sangelos * You may use this code under the GNU public license if you so wish. Please
12b474cdc2Sangelos * contribute changes back to the authors under this freer than GPL license
13b474cdc2Sangelos * so that we may further the use of strong encryption without limitations to
14b474cdc2Sangelos * all.
15b474cdc2Sangelos *
16b474cdc2Sangelos * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
17b474cdc2Sangelos * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
18b474cdc2Sangelos * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
19b474cdc2Sangelos * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
20b474cdc2Sangelos * PURPOSE.
21b474cdc2Sangelos */
22b474cdc2Sangelos
2312e5c931Sguenther #include <netinet/in.h>
24b474cdc2Sangelos #include <string.h>
2516bd75f4Sho #include <stdlib.h>
26b474cdc2Sangelos
27b474cdc2Sangelos #include "key.h"
289bdcc5e3Sho #include "libcrypto.h"
299bdcc5e3Sho #include "log.h"
309bdcc5e3Sho #include "util.h"
31b474cdc2Sangelos #include "x509.h"
32b474cdc2Sangelos
33b474cdc2Sangelos void
key_free(int type,int private,void * key)34b474cdc2Sangelos key_free(int type, int private, void *key)
35b474cdc2Sangelos {
36fb9475d6Sderaadt switch (type) {
37b474cdc2Sangelos case ISAKMP_KEY_PASSPHRASE:
38b474cdc2Sangelos free(key);
39b474cdc2Sangelos break;
40b474cdc2Sangelos case ISAKMP_KEY_RSA:
41f61a65acSho RSA_free(key);
42b474cdc2Sangelos break;
43b474cdc2Sangelos case ISAKMP_KEY_NONE:
44b474cdc2Sangelos default:
45b474cdc2Sangelos log_error("key_free: unknown/unsupportedkey type %d", type);
46b474cdc2Sangelos break;
47b474cdc2Sangelos }
48b474cdc2Sangelos }
49b474cdc2Sangelos
50b474cdc2Sangelos /* Convert from internal form to serialized */
51b474cdc2Sangelos void
key_serialize(int type,int private,void * key,u_int8_t ** data,size_t * datalenp)5212f43dabShshoexer key_serialize(int type, int private, void *key, u_int8_t **data,
5312f43dabShshoexer size_t *datalenp)
54b474cdc2Sangelos {
55b474cdc2Sangelos u_int8_t *p;
567cf7c1b3Sderaadt size_t datalen;
57b474cdc2Sangelos
58fb9475d6Sderaadt switch (type) {
59b474cdc2Sangelos case ISAKMP_KEY_PASSPHRASE:
607cf7c1b3Sderaadt *datalenp = strlen((char *)key);
61b26670e8Sho *data = (u_int8_t *)strdup((char *)key);
62b474cdc2Sangelos break;
63b474cdc2Sangelos case ISAKMP_KEY_RSA:
64fb9475d6Sderaadt switch (private) {
65b474cdc2Sangelos case ISAKMP_KEYTYPE_PUBLIC:
667cf7c1b3Sderaadt datalen = i2d_RSAPublicKey((RSA *)key, NULL);
677cf7c1b3Sderaadt *data = p = malloc(datalen);
68fb9475d6Sderaadt if (!p) {
697eb3b581Sderaadt log_error("key_serialize: malloc (%lu) failed",
707cf7c1b3Sderaadt (unsigned long)datalen);
71b474cdc2Sangelos return;
72b474cdc2Sangelos }
737cf7c1b3Sderaadt *datalenp = i2d_RSAPublicKey((RSA *) key, &p);
74b474cdc2Sangelos break;
750eb823c5Sniklas
76b474cdc2Sangelos case ISAKMP_KEYTYPE_PRIVATE:
777cf7c1b3Sderaadt datalen = i2d_RSAPrivateKey((RSA *)key, NULL);
787cf7c1b3Sderaadt *data = p = malloc(datalen);
79fb9475d6Sderaadt if (!p) {
807eb3b581Sderaadt log_error("key_serialize: malloc (%lu) failed",
817cf7c1b3Sderaadt (unsigned long)datalen);
82b474cdc2Sangelos return;
83b474cdc2Sangelos }
847cf7c1b3Sderaadt *datalenp = i2d_RSAPrivateKey((RSA *)key, &p);
85b474cdc2Sangelos break;
86b474cdc2Sangelos }
87b474cdc2Sangelos break;
88b474cdc2Sangelos default:
8912f43dabShshoexer log_error("key_serialize: unknown/unsupported key type %d",
9012f43dabShshoexer type);
91b474cdc2Sangelos break;
92b474cdc2Sangelos }
93b474cdc2Sangelos }
94b474cdc2Sangelos
95b474cdc2Sangelos /* Convert from serialized to printable */
96b474cdc2Sangelos char *
key_printable(int type,int private,u_int8_t * data,size_t datalen)975303c0dcScloder key_printable(int type, int private, u_int8_t *data, size_t datalen)
98b474cdc2Sangelos {
99fb9475d6Sderaadt switch (type) {
100b474cdc2Sangelos case ISAKMP_KEY_PASSPHRASE:
101b474cdc2Sangelos return strdup((char *)data);
1020eb823c5Sniklas
103b474cdc2Sangelos case ISAKMP_KEY_RSA:
104d6d7f0d1Scloder return raw2hex(data, datalen);
1050eb823c5Sniklas
106b474cdc2Sangelos default:
10712f43dabShshoexer log_error("key_printable: unknown/unsupported key type %d",
10812f43dabShshoexer type);
1090eb823c5Sniklas return 0;
110b474cdc2Sangelos }
111b474cdc2Sangelos }
112b474cdc2Sangelos
1130eb823c5Sniklas /* Convert from serialized to internal. */
114b474cdc2Sangelos void *
key_internalize(int type,int private,u_int8_t * data,size_t datalen)1155303c0dcScloder key_internalize(int type, int private, u_int8_t *data, size_t datalen)
116b474cdc2Sangelos {
117fb9475d6Sderaadt switch (type) {
118b474cdc2Sangelos case ISAKMP_KEY_PASSPHRASE:
119b26670e8Sho return strdup((char *)data);
120b474cdc2Sangelos case ISAKMP_KEY_RSA:
121fb9475d6Sderaadt switch (private) {
122a852d5beSho case ISAKMP_KEYTYPE_PUBLIC:
123fb9475d6Sderaadt return d2i_RSAPublicKey(NULL,
124fb9475d6Sderaadt (const u_int8_t **)&data, datalen);
125a852d5beSho case ISAKMP_KEYTYPE_PRIVATE:
126fb9475d6Sderaadt return d2i_RSAPrivateKey(NULL,
127fb9475d6Sderaadt (const u_int8_t **)&data, datalen);
128b474cdc2Sangelos default:
129fb9475d6Sderaadt log_error("key_internalize: not public or private "
130fb9475d6Sderaadt "RSA key passed");
1310eb823c5Sniklas return 0;
132b474cdc2Sangelos }
133b474cdc2Sangelos break;
134b474cdc2Sangelos default:
135fb9475d6Sderaadt log_error("key_internalize: unknown/unsupported key type %d",
136fb9475d6Sderaadt type);
137b474cdc2Sangelos break;
138b474cdc2Sangelos }
139b474cdc2Sangelos
1400eb823c5Sniklas return 0;
141b474cdc2Sangelos }
142b474cdc2Sangelos
143b474cdc2Sangelos /* Convert from printable to serialized */
144b474cdc2Sangelos void
key_from_printable(int type,int private,char * key,u_int8_t ** data,u_int32_t * datalenp)145b474cdc2Sangelos key_from_printable(int type, int private, char *key, u_int8_t **data,
1467cf7c1b3Sderaadt u_int32_t *datalenp)
147b474cdc2Sangelos {
1487cf7c1b3Sderaadt u_int32_t datalen;
1497cf7c1b3Sderaadt
150fb9475d6Sderaadt switch (type) {
151b474cdc2Sangelos case ISAKMP_KEY_PASSPHRASE:
1527cf7c1b3Sderaadt *datalenp = strlen(key);
153b26670e8Sho *data = (u_int8_t *) strdup(key);
154b474cdc2Sangelos break;
1550eb823c5Sniklas
156b474cdc2Sangelos case ISAKMP_KEY_RSA:
1577cf7c1b3Sderaadt datalen = (strlen(key) + 1) / 2; /* Round up, just in case */
1587cf7c1b3Sderaadt *data = malloc(datalen);
159fb9475d6Sderaadt if (!*data) {
16012f43dabShshoexer log_error("key_from_printable: malloc (%d) failed",
16112f43dabShshoexer datalen);
1627cf7c1b3Sderaadt *datalenp = 0;
163b474cdc2Sangelos return;
164b474cdc2Sangelos }
1655e8798e2Shshoexer if (hex2raw(key, *data, datalen)) {
1665e8798e2Shshoexer log_error("key_from_printable: invalid hex key");
1675e8798e2Shshoexer free(*data);
168e1e6e172Smoritz *data = NULL;
1695e8798e2Shshoexer *datalenp = 0;
1705e8798e2Shshoexer return;
1715e8798e2Shshoexer }
1725e8798e2Shshoexer *datalenp = datalen;
173b474cdc2Sangelos break;
1740eb823c5Sniklas
175b474cdc2Sangelos default:
17650eea14cSho log_error("key_from_printable: "
17750eea14cSho "unknown/unsupported key type %d", type);
1787cf7c1b3Sderaadt *data = NULL;
1797cf7c1b3Sderaadt *datalenp = 0;
180b474cdc2Sangelos break;
181b474cdc2Sangelos }
182b474cdc2Sangelos }
183