1/* 2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by Markus Friedl. 15 * 4. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 *
| 1/* 2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by Markus Friedl. 15 * 4. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 *
|
29 * $FreeBSD: head/crypto/openssh/key.c 60576 2000-05-15 05:24:25Z kris $
| 29 * $FreeBSD: head/crypto/openssh/key.c 61203 2000-06-03 07:31:44Z kris $
|
30 */ 31/* 32 * read_bignum(): 33 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 34 */ 35 36#include "includes.h" 37#include "ssh.h" 38#include <openssl/rsa.h> 39#include <openssl/dsa.h> 40#include <openssl/evp.h> 41#include "xmalloc.h" 42#include "key.h" 43#include "dsa.h" 44#include "uuencode.h" 45 46#define SSH_DSS "ssh-dss" 47 48Key * 49key_new(int type) 50{ 51 Key *k; 52 RSA *rsa; 53 DSA *dsa; 54 k = xmalloc(sizeof(*k)); 55 k->type = type; 56 k->dsa = NULL; 57 k->rsa = NULL; 58 switch (k->type) { 59 case KEY_RSA: 60 rsa = RSA_new(); 61 rsa->n = BN_new(); 62 rsa->e = BN_new(); 63 k->rsa = rsa; 64 break; 65 case KEY_DSA: 66 dsa = DSA_new(); 67 dsa->p = BN_new(); 68 dsa->q = BN_new(); 69 dsa->g = BN_new(); 70 dsa->pub_key = BN_new(); 71 k->dsa = dsa; 72 break; 73 case KEY_EMPTY: 74 break; 75 default: 76 fatal("key_new: bad key type %d", k->type); 77 break; 78 } 79 return k; 80} 81void 82key_free(Key *k) 83{ 84 switch (k->type) { 85 case KEY_RSA: 86 if (k->rsa != NULL) 87 RSA_free(k->rsa); 88 k->rsa = NULL; 89 break; 90 case KEY_DSA: 91 if (k->dsa != NULL) 92 DSA_free(k->dsa); 93 k->dsa = NULL; 94 break; 95 default: 96 fatal("key_free: bad key type %d", k->type); 97 break; 98 } 99 xfree(k); 100} 101int 102key_equal(Key *a, Key *b) 103{ 104 if (a == NULL || b == NULL || a->type != b->type) 105 return 0; 106 switch (a->type) { 107 case KEY_RSA: 108 return a->rsa != NULL && b->rsa != NULL && 109 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 110 BN_cmp(a->rsa->n, b->rsa->n) == 0; 111 break; 112 case KEY_DSA: 113 return a->dsa != NULL && b->dsa != NULL && 114 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 115 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 116 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 117 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 118 break; 119 default: 120 fatal("key_equal: bad key type %d", a->type); 121 break; 122 } 123 return 0; 124} 125 126#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" 127 128/* 129 * Generate key fingerprint in ascii format. 130 * Based on ideas and code from Bjoern Groenvall <bg@sics.se> 131 */ 132char * 133key_fingerprint(Key *k) 134{ 135 static char retval[80]; 136 unsigned char *blob = NULL; 137 int len = 0; 138 int nlen, elen; 139 140 switch (k->type) { 141 case KEY_RSA: 142 nlen = BN_num_bytes(k->rsa->n); 143 elen = BN_num_bytes(k->rsa->e); 144 len = nlen + elen; 145 blob = xmalloc(len); 146 BN_bn2bin(k->rsa->n, blob); 147 BN_bn2bin(k->rsa->e, blob + nlen); 148 break; 149 case KEY_DSA: 150 dsa_make_key_blob(k, &blob, &len); 151 break; 152 default: 153 fatal("key_fingerprint: bad key type %d", k->type); 154 break; 155 } 156 if (blob != NULL) { 157 unsigned char d[16]; 158 EVP_MD_CTX md; 159 EVP_DigestInit(&md, EVP_md5()); 160 EVP_DigestUpdate(&md, blob, len); 161 EVP_DigestFinal(&md, d, NULL); 162 snprintf(retval, sizeof(retval), FPRINT, 163 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], 164 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 165 memset(blob, 0, len); 166 xfree(blob); 167 } 168 return retval; 169} 170 171/* 172 * Reads a multiple-precision integer in decimal from the buffer, and advances 173 * the pointer. The integer must already be initialized. This function is 174 * permitted to modify the buffer. This leaves *cpp to point just beyond the 175 * last processed (and maybe modified) character. Note that this may modify 176 * the buffer containing the number. 177 */ 178int 179read_bignum(char **cpp, BIGNUM * value) 180{ 181 char *cp = *cpp; 182 int old; 183 184 /* Skip any leading whitespace. */ 185 for (; *cp == ' ' || *cp == '\t'; cp++) 186 ; 187 188 /* Check that it begins with a decimal digit. */ 189 if (*cp < '0' || *cp > '9') 190 return 0; 191 192 /* Save starting position. */ 193 *cpp = cp; 194 195 /* Move forward until all decimal digits skipped. */ 196 for (; *cp >= '0' && *cp <= '9'; cp++) 197 ; 198 199 /* Save the old terminating character, and replace it by \0. */ 200 old = *cp; 201 *cp = 0; 202 203 /* Parse the number. */ 204 if (BN_dec2bn(&value, *cpp) == 0) 205 return 0; 206 207 /* Restore old terminating character. */ 208 *cp = old; 209 210 /* Move beyond the number and return success. */ 211 *cpp = cp; 212 return 1; 213} 214int 215write_bignum(FILE *f, BIGNUM *num) 216{ 217 char *buf = BN_bn2dec(num); 218 if (buf == NULL) { 219 error("write_bignum: BN_bn2dec() failed"); 220 return 0; 221 } 222 fprintf(f, " %s", buf); 223 free(buf); 224 return 1; 225} 226unsigned int 227key_read(Key *ret, char **cpp) 228{ 229 Key *k; 230 unsigned int bits = 0; 231 char *cp; 232 int len, n; 233 unsigned char *blob; 234 235 cp = *cpp; 236 237 switch(ret->type) { 238 case KEY_RSA: 239 /* Get number of bits. */ 240 if (*cp < '0' || *cp > '9') 241 return 0; /* Bad bit count... */ 242 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 243 bits = 10 * bits + *cp - '0'; 244 if (bits == 0) 245 return 0; 246 *cpp = cp; 247 /* Get public exponent, public modulus. */ 248 if (!read_bignum(cpp, ret->rsa->e)) 249 return 0; 250 if (!read_bignum(cpp, ret->rsa->n)) 251 return 0; 252 break; 253 case KEY_DSA: 254 if (strncmp(cp, SSH_DSS " ", 7) != 0) 255 return 0; 256 cp += 7; 257 len = 2*strlen(cp); 258 blob = xmalloc(len); 259 n = uudecode(cp, blob, len); 260 if (n < 0) {
| 30 */ 31/* 32 * read_bignum(): 33 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 34 */ 35 36#include "includes.h" 37#include "ssh.h" 38#include <openssl/rsa.h> 39#include <openssl/dsa.h> 40#include <openssl/evp.h> 41#include "xmalloc.h" 42#include "key.h" 43#include "dsa.h" 44#include "uuencode.h" 45 46#define SSH_DSS "ssh-dss" 47 48Key * 49key_new(int type) 50{ 51 Key *k; 52 RSA *rsa; 53 DSA *dsa; 54 k = xmalloc(sizeof(*k)); 55 k->type = type; 56 k->dsa = NULL; 57 k->rsa = NULL; 58 switch (k->type) { 59 case KEY_RSA: 60 rsa = RSA_new(); 61 rsa->n = BN_new(); 62 rsa->e = BN_new(); 63 k->rsa = rsa; 64 break; 65 case KEY_DSA: 66 dsa = DSA_new(); 67 dsa->p = BN_new(); 68 dsa->q = BN_new(); 69 dsa->g = BN_new(); 70 dsa->pub_key = BN_new(); 71 k->dsa = dsa; 72 break; 73 case KEY_EMPTY: 74 break; 75 default: 76 fatal("key_new: bad key type %d", k->type); 77 break; 78 } 79 return k; 80} 81void 82key_free(Key *k) 83{ 84 switch (k->type) { 85 case KEY_RSA: 86 if (k->rsa != NULL) 87 RSA_free(k->rsa); 88 k->rsa = NULL; 89 break; 90 case KEY_DSA: 91 if (k->dsa != NULL) 92 DSA_free(k->dsa); 93 k->dsa = NULL; 94 break; 95 default: 96 fatal("key_free: bad key type %d", k->type); 97 break; 98 } 99 xfree(k); 100} 101int 102key_equal(Key *a, Key *b) 103{ 104 if (a == NULL || b == NULL || a->type != b->type) 105 return 0; 106 switch (a->type) { 107 case KEY_RSA: 108 return a->rsa != NULL && b->rsa != NULL && 109 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 110 BN_cmp(a->rsa->n, b->rsa->n) == 0; 111 break; 112 case KEY_DSA: 113 return a->dsa != NULL && b->dsa != NULL && 114 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 115 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 116 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 117 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 118 break; 119 default: 120 fatal("key_equal: bad key type %d", a->type); 121 break; 122 } 123 return 0; 124} 125 126#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" 127 128/* 129 * Generate key fingerprint in ascii format. 130 * Based on ideas and code from Bjoern Groenvall <bg@sics.se> 131 */ 132char * 133key_fingerprint(Key *k) 134{ 135 static char retval[80]; 136 unsigned char *blob = NULL; 137 int len = 0; 138 int nlen, elen; 139 140 switch (k->type) { 141 case KEY_RSA: 142 nlen = BN_num_bytes(k->rsa->n); 143 elen = BN_num_bytes(k->rsa->e); 144 len = nlen + elen; 145 blob = xmalloc(len); 146 BN_bn2bin(k->rsa->n, blob); 147 BN_bn2bin(k->rsa->e, blob + nlen); 148 break; 149 case KEY_DSA: 150 dsa_make_key_blob(k, &blob, &len); 151 break; 152 default: 153 fatal("key_fingerprint: bad key type %d", k->type); 154 break; 155 } 156 if (blob != NULL) { 157 unsigned char d[16]; 158 EVP_MD_CTX md; 159 EVP_DigestInit(&md, EVP_md5()); 160 EVP_DigestUpdate(&md, blob, len); 161 EVP_DigestFinal(&md, d, NULL); 162 snprintf(retval, sizeof(retval), FPRINT, 163 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], 164 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 165 memset(blob, 0, len); 166 xfree(blob); 167 } 168 return retval; 169} 170 171/* 172 * Reads a multiple-precision integer in decimal from the buffer, and advances 173 * the pointer. The integer must already be initialized. This function is 174 * permitted to modify the buffer. This leaves *cpp to point just beyond the 175 * last processed (and maybe modified) character. Note that this may modify 176 * the buffer containing the number. 177 */ 178int 179read_bignum(char **cpp, BIGNUM * value) 180{ 181 char *cp = *cpp; 182 int old; 183 184 /* Skip any leading whitespace. */ 185 for (; *cp == ' ' || *cp == '\t'; cp++) 186 ; 187 188 /* Check that it begins with a decimal digit. */ 189 if (*cp < '0' || *cp > '9') 190 return 0; 191 192 /* Save starting position. */ 193 *cpp = cp; 194 195 /* Move forward until all decimal digits skipped. */ 196 for (; *cp >= '0' && *cp <= '9'; cp++) 197 ; 198 199 /* Save the old terminating character, and replace it by \0. */ 200 old = *cp; 201 *cp = 0; 202 203 /* Parse the number. */ 204 if (BN_dec2bn(&value, *cpp) == 0) 205 return 0; 206 207 /* Restore old terminating character. */ 208 *cp = old; 209 210 /* Move beyond the number and return success. */ 211 *cpp = cp; 212 return 1; 213} 214int 215write_bignum(FILE *f, BIGNUM *num) 216{ 217 char *buf = BN_bn2dec(num); 218 if (buf == NULL) { 219 error("write_bignum: BN_bn2dec() failed"); 220 return 0; 221 } 222 fprintf(f, " %s", buf); 223 free(buf); 224 return 1; 225} 226unsigned int 227key_read(Key *ret, char **cpp) 228{ 229 Key *k; 230 unsigned int bits = 0; 231 char *cp; 232 int len, n; 233 unsigned char *blob; 234 235 cp = *cpp; 236 237 switch(ret->type) { 238 case KEY_RSA: 239 /* Get number of bits. */ 240 if (*cp < '0' || *cp > '9') 241 return 0; /* Bad bit count... */ 242 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 243 bits = 10 * bits + *cp - '0'; 244 if (bits == 0) 245 return 0; 246 *cpp = cp; 247 /* Get public exponent, public modulus. */ 248 if (!read_bignum(cpp, ret->rsa->e)) 249 return 0; 250 if (!read_bignum(cpp, ret->rsa->n)) 251 return 0; 252 break; 253 case KEY_DSA: 254 if (strncmp(cp, SSH_DSS " ", 7) != 0) 255 return 0; 256 cp += 7; 257 len = 2*strlen(cp); 258 blob = xmalloc(len); 259 n = uudecode(cp, blob, len); 260 if (n < 0) {
|
261 error("uudecode %s failed", cp);
| 261 error("key_read: uudecode %s failed", cp);
|
262 return 0; 263 } 264 k = dsa_key_from_blob(blob, n);
| 262 return 0; 263 } 264 k = dsa_key_from_blob(blob, n);
|
265 if (k == NULL) 266 return 0;
| 265 if (k == NULL) { 266 error("key_read: dsa_key_from_blob %s failed", cp); 267 return 0; 268 }
|
267 xfree(blob); 268 if (ret->dsa != NULL) 269 DSA_free(ret->dsa); 270 ret->dsa = k->dsa; 271 k->dsa = NULL; 272 key_free(k); 273 bits = BN_num_bits(ret->dsa->p);
| 269 xfree(blob); 270 if (ret->dsa != NULL) 271 DSA_free(ret->dsa); 272 ret->dsa = k->dsa; 273 k->dsa = NULL; 274 key_free(k); 275 bits = BN_num_bits(ret->dsa->p);
|
274 cp = strchr(cp, '='); 275 if (cp == NULL) 276 return 0; 277 *cpp = cp + 1;
| 276 /* advance cp: skip whitespace and data */ 277 while (*cp == ' ' || *cp == '\t') 278 cp++; 279 while (*cp != '\0' && *cp != ' ' && *cp != '\t') 280 cp++; 281 *cpp = cp;
|
278 break; 279 default: 280 fatal("key_read: bad key type: %d", ret->type); 281 break; 282 } 283 return bits; 284} 285int 286key_write(Key *key, FILE *f) 287{ 288 int success = 0; 289 unsigned int bits = 0; 290 291 if (key->type == KEY_RSA && key->rsa != NULL) { 292 /* size of modulus 'n' */ 293 bits = BN_num_bits(key->rsa->n); 294 fprintf(f, "%u", bits); 295 if (write_bignum(f, key->rsa->e) && 296 write_bignum(f, key->rsa->n)) { 297 success = 1; 298 } else { 299 error("key_write: failed for RSA key"); 300 } 301 } else if (key->type == KEY_DSA && key->dsa != NULL) { 302 int len, n; 303 unsigned char *blob, *uu; 304 dsa_make_key_blob(key, &blob, &len); 305 uu = xmalloc(2*len); 306 n = uuencode(blob, len, uu, 2*len); 307 if (n > 0) { 308 fprintf(f, "%s %s", SSH_DSS, uu); 309 success = 1; 310 } 311 xfree(blob); 312 xfree(uu); 313 } 314 return success; 315} 316char * 317key_type(Key *k) 318{ 319 switch (k->type) { 320 case KEY_RSA: 321 return "RSA"; 322 break; 323 case KEY_DSA: 324 return "DSA"; 325 break; 326 } 327 return "unknown"; 328}
| 282 break; 283 default: 284 fatal("key_read: bad key type: %d", ret->type); 285 break; 286 } 287 return bits; 288} 289int 290key_write(Key *key, FILE *f) 291{ 292 int success = 0; 293 unsigned int bits = 0; 294 295 if (key->type == KEY_RSA && key->rsa != NULL) { 296 /* size of modulus 'n' */ 297 bits = BN_num_bits(key->rsa->n); 298 fprintf(f, "%u", bits); 299 if (write_bignum(f, key->rsa->e) && 300 write_bignum(f, key->rsa->n)) { 301 success = 1; 302 } else { 303 error("key_write: failed for RSA key"); 304 } 305 } else if (key->type == KEY_DSA && key->dsa != NULL) { 306 int len, n; 307 unsigned char *blob, *uu; 308 dsa_make_key_blob(key, &blob, &len); 309 uu = xmalloc(2*len); 310 n = uuencode(blob, len, uu, 2*len); 311 if (n > 0) { 312 fprintf(f, "%s %s", SSH_DSS, uu); 313 success = 1; 314 } 315 xfree(blob); 316 xfree(uu); 317 } 318 return success; 319} 320char * 321key_type(Key *k) 322{ 323 switch (k->type) { 324 case KEY_RSA: 325 return "RSA"; 326 break; 327 case KEY_DSA: 328 return "DSA"; 329 break; 330 } 331 return "unknown"; 332}
|