xref: /openbsd-src/sbin/isakmpd/key.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: key.c,v 1.4 2001/07/02 02:28:35 deraadt Exp $	*/
2 /*
3  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
4  *
5  * Copyright (c) 2000-2001 Angelos D. Keromytis.
6  *
7  * Permission to use, copy, and modify this software with or without fee
8  * is hereby granted, provided that this entire notice is included in
9  * all copies of any software which is or includes a copy or
10  * modification of this software.
11  * You may use this code under the GNU public license if you so wish. Please
12  * contribute changes back to the authors under this freer than GPL license
13  * so that we may further the use of strong encryption without limitations to
14  * all.
15  *
16  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
18  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
19  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
20  * PURPOSE.
21  */
22 
23 #include <string.h>
24 
25 #include "sysdep.h"
26 
27 #include "dyn.h"
28 #include "util.h"
29 #include "log.h"
30 #include "key.h"
31 #include "x509.h"
32 
33 void
34 key_free (int type, int private, void *key)
35 {
36   switch (type)
37     {
38     case ISAKMP_KEY_PASSPHRASE:
39       free (key);
40       break;
41     case ISAKMP_KEY_RSA:
42       LC (RSA_free, (key));
43       break;
44     case ISAKMP_KEY_NONE:
45     default:
46       log_error ("key_free: unknown/unsupportedkey type %d", type);
47       break;
48     }
49 }
50 
51 /* Convert from internal form to serialized */
52 void
53 key_serialize (int type, int private, void *key, u_int8_t **data, size_t *datalen)
54 {
55   u_int8_t *p;
56 
57   switch (type)
58     {
59     case ISAKMP_KEY_PASSPHRASE:
60       *datalen = strlen ((char *)key);
61       *data = strdup ((char *)key);
62       break;
63     case ISAKMP_KEY_RSA:
64       switch (private)
65 	{
66 	case ISAKMP_KEYTYPE_PUBLIC:
67 	  *datalen = LC (i2d_RSAPublicKey, ((RSA *)key, NULL));
68 	  *data = p = malloc (*datalen);
69 	  if (!p)
70 	    {
71 	      log_error("key_serialize: malloc (%d) failed", *datalen);
72 	      return;
73 	    }
74 	  *datalen = LC (i2d_RSAPublicKey, ((RSA *)key, &p));
75 	  break;
76 
77 	case ISAKMP_KEYTYPE_PRIVATE:
78 	  *datalen = LC (i2d_RSAPrivateKey, ((RSA *)key, NULL));
79 	  *data = p = malloc (*datalen);
80 	  if (!p)
81 	    {
82 	      log_error("key_serialize: malloc (%d) failed", *datalen);
83 	      return;
84 	    }
85 	  *datalen = LC (i2d_RSAPrivateKey, ((RSA *)key, &p));
86 	  break;
87 	}
88       break;
89     default:
90       log_error ("key_serialize: unknown/unsupported key type %d", type);
91       break;
92     }
93 }
94 
95 /* Convert from serialized to printable */
96 char *
97 key_printable (int type, int private, u_int8_t *data, int datalen)
98 {
99   char *s;
100   int i;
101 
102   switch (type)
103     {
104     case ISAKMP_KEY_PASSPHRASE:
105       return strdup ((char *)data);
106 
107     case ISAKMP_KEY_RSA:
108       s = malloc (datalen * 2);
109       if (!s)
110 	{
111 	  log_error ("key_printable: malloc (%d) failed", datalen * 2);
112 	  return 0;
113 	}
114       for (i = 0; i < datalen; i++)
115 	sprintf (s + (2 * i), "%02x", data[i]);
116       return s;
117 
118     default:
119       log_error ("key_printable: unknown/unsupported key type %d", type);
120       return 0;
121     }
122 }
123 
124 /* Convert from serialized to internal.  */
125 void *
126 key_internalize (int type, int private, u_int8_t *data, int datalen)
127 {
128   switch (type)
129     {
130     case ISAKMP_KEY_PASSPHRASE:
131       return strdup (data);
132     case ISAKMP_KEY_RSA:
133       switch (private)
134 	{
135 	case ISAKMP_KEYTYPE_PUBLIC:
136 	  return LC (d2i_RSAPublicKey, (NULL, &data, datalen));
137 	case ISAKMP_KEYTYPE_PRIVATE:
138 	  return LC (d2i_RSAPrivateKey, (NULL, &data, datalen));
139 	default:
140 	  log_error ("key_internalize: not public or private RSA key passed");
141 	  return 0;
142 	}
143       break;
144     default:
145       log_error ("key_internalize: unknown/unsupported key type %d", type);
146       break;
147     }
148 
149   return 0;
150 }
151 
152 /* Convert from printable to serialized */
153 void
154 key_from_printable (int type, int private, char *key, u_int8_t **data,
155 		    int *datalen)
156 {
157   switch (type)
158     {
159     case ISAKMP_KEY_PASSPHRASE:
160       *datalen = strlen (key);
161       *data = strdup (key);
162       break;
163 
164     case ISAKMP_KEY_RSA:
165       *datalen = (strlen (key) + 1) / 2; /* Round up, just in case */
166       *data = malloc (*datalen);
167       if (!*data)
168 	{
169 	  log_error ("key_from_printable: malloc (%d) failed", *datalen);
170 	  return;
171 	}
172       *datalen = hex2raw (key, *data, *datalen);
173       break;
174 
175     default:
176       log_error ("key_from_printable: unknown/unsupported key type %d", type);
177       break;
178     }
179 }
180