xref: /openbsd-src/sbin/isakmpd/key.c (revision 99fc1771582867a3a720a425dd5535f017e895a3)
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