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