1 /* $OpenBSD: key.c,v 1.27 2021/10/13 16:57:43 tb 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 <netinet/in.h> 24 #include <string.h> 25 #include <stdlib.h> 26 27 #include "key.h" 28 #include "libcrypto.h" 29 #include "log.h" 30 #include "util.h" 31 #include "x509.h" 32 33 void 34 key_free(int type, int private, void *key) 35 { 36 switch (type) { 37 case ISAKMP_KEY_PASSPHRASE: 38 free(key); 39 break; 40 case ISAKMP_KEY_RSA: 41 RSA_free(key); 42 break; 43 case ISAKMP_KEY_NONE: 44 default: 45 log_error("key_free: unknown/unsupportedkey type %d", type); 46 break; 47 } 48 } 49 50 /* Convert from internal form to serialized */ 51 void 52 key_serialize(int type, int private, void *key, u_int8_t **data, 53 size_t *datalenp) 54 { 55 u_int8_t *p; 56 size_t datalen; 57 58 switch (type) { 59 case ISAKMP_KEY_PASSPHRASE: 60 *datalenp = strlen((char *)key); 61 *data = (u_int8_t *)strdup((char *)key); 62 break; 63 case ISAKMP_KEY_RSA: 64 switch (private) { 65 case ISAKMP_KEYTYPE_PUBLIC: 66 datalen = i2d_RSAPublicKey((RSA *)key, NULL); 67 *data = p = malloc(datalen); 68 if (!p) { 69 log_error("key_serialize: malloc (%lu) failed", 70 (unsigned long)datalen); 71 return; 72 } 73 *datalenp = i2d_RSAPublicKey((RSA *) key, &p); 74 break; 75 76 case ISAKMP_KEYTYPE_PRIVATE: 77 datalen = i2d_RSAPrivateKey((RSA *)key, NULL); 78 *data = p = malloc(datalen); 79 if (!p) { 80 log_error("key_serialize: malloc (%lu) failed", 81 (unsigned long)datalen); 82 return; 83 } 84 *datalenp = i2d_RSAPrivateKey((RSA *)key, &p); 85 break; 86 } 87 break; 88 default: 89 log_error("key_serialize: unknown/unsupported key type %d", 90 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, size_t datalen) 98 { 99 switch (type) { 100 case ISAKMP_KEY_PASSPHRASE: 101 return strdup((char *)data); 102 103 case ISAKMP_KEY_RSA: 104 return raw2hex(data, datalen); 105 106 default: 107 log_error("key_printable: unknown/unsupported key type %d", 108 type); 109 return 0; 110 } 111 } 112 113 /* Convert from serialized to internal. */ 114 void * 115 key_internalize(int type, int private, u_int8_t *data, size_t datalen) 116 { 117 switch (type) { 118 case ISAKMP_KEY_PASSPHRASE: 119 return strdup((char *)data); 120 case ISAKMP_KEY_RSA: 121 switch (private) { 122 case ISAKMP_KEYTYPE_PUBLIC: 123 return d2i_RSAPublicKey(NULL, 124 (const u_int8_t **)&data, datalen); 125 case ISAKMP_KEYTYPE_PRIVATE: 126 return d2i_RSAPrivateKey(NULL, 127 (const u_int8_t **)&data, datalen); 128 default: 129 log_error("key_internalize: not public or private " 130 "RSA key passed"); 131 return 0; 132 } 133 break; 134 default: 135 log_error("key_internalize: unknown/unsupported key type %d", 136 type); 137 break; 138 } 139 140 return 0; 141 } 142 143 /* Convert from printable to serialized */ 144 void 145 key_from_printable(int type, int private, char *key, u_int8_t **data, 146 u_int32_t *datalenp) 147 { 148 u_int32_t datalen; 149 150 switch (type) { 151 case ISAKMP_KEY_PASSPHRASE: 152 *datalenp = strlen(key); 153 *data = (u_int8_t *) strdup(key); 154 break; 155 156 case ISAKMP_KEY_RSA: 157 datalen = (strlen(key) + 1) / 2; /* Round up, just in case */ 158 *data = malloc(datalen); 159 if (!*data) { 160 log_error("key_from_printable: malloc (%d) failed", 161 datalen); 162 *datalenp = 0; 163 return; 164 } 165 if (hex2raw(key, *data, datalen)) { 166 log_error("key_from_printable: invalid hex key"); 167 free(*data); 168 *data = NULL; 169 *datalenp = 0; 170 return; 171 } 172 *datalenp = datalen; 173 break; 174 175 default: 176 log_error("key_from_printable: " 177 "unknown/unsupported key type %d", type); 178 *data = NULL; 179 *datalenp = 0; 180 break; 181 } 182 } 183