diff options
author | Damien Miller <djm@mindrot.org> | 2013-12-07 10:40:26 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2013-12-07 10:40:26 +1100 |
commit | f0e9060d236c0e38bec2fa1c6579fb0a2ea6458d (patch) | |
tree | 3ad8b9719e35b7f7e0a4ae2d012f6e8ee5160dcc /key.c | |
parent | 0f8536da23a6ef26e6495177c0d8a4242b710289 (diff) |
- markus@cvs.openbsd.org 2013/12/06 13:30:08
[authfd.c key.c key.h ssh-agent.c]
move private key (de)serialization to key.c; ok djm
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 193 |
1 files changed, 192 insertions, 1 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.106 2013/12/02 03:09:22 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.107 2013/12/06 13:30:08 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -2276,3 +2276,194 @@ key_dump_ec_key(const EC_KEY *key) | |||
2276 | } | 2276 | } |
2277 | #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ | 2277 | #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ |
2278 | #endif /* OPENSSL_HAS_ECC */ | 2278 | #endif /* OPENSSL_HAS_ECC */ |
2279 | |||
2280 | void | ||
2281 | key_private_serialize(const Key *key, Buffer *b) | ||
2282 | { | ||
2283 | buffer_put_cstring(b, key_ssh_name(key)); | ||
2284 | switch (key->type) { | ||
2285 | case KEY_RSA: | ||
2286 | buffer_put_bignum2(b, key->rsa->n); | ||
2287 | buffer_put_bignum2(b, key->rsa->e); | ||
2288 | buffer_put_bignum2(b, key->rsa->d); | ||
2289 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2290 | buffer_put_bignum2(b, key->rsa->p); | ||
2291 | buffer_put_bignum2(b, key->rsa->q); | ||
2292 | break; | ||
2293 | case KEY_RSA_CERT_V00: | ||
2294 | case KEY_RSA_CERT: | ||
2295 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2296 | fatal("%s: no cert/certblob", __func__); | ||
2297 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2298 | buffer_len(&key->cert->certblob)); | ||
2299 | buffer_put_bignum2(b, key->rsa->d); | ||
2300 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2301 | buffer_put_bignum2(b, key->rsa->p); | ||
2302 | buffer_put_bignum2(b, key->rsa->q); | ||
2303 | break; | ||
2304 | case KEY_DSA: | ||
2305 | buffer_put_bignum2(b, key->dsa->p); | ||
2306 | buffer_put_bignum2(b, key->dsa->q); | ||
2307 | buffer_put_bignum2(b, key->dsa->g); | ||
2308 | buffer_put_bignum2(b, key->dsa->pub_key); | ||
2309 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2310 | break; | ||
2311 | case KEY_DSA_CERT_V00: | ||
2312 | case KEY_DSA_CERT: | ||
2313 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2314 | fatal("%s: no cert/certblob", __func__); | ||
2315 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2316 | buffer_len(&key->cert->certblob)); | ||
2317 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2318 | break; | ||
2319 | #ifdef OPENSSL_HAS_ECC | ||
2320 | case KEY_ECDSA: | ||
2321 | buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
2322 | buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), | ||
2323 | EC_KEY_get0_public_key(key->ecdsa)); | ||
2324 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2325 | break; | ||
2326 | case KEY_ECDSA_CERT: | ||
2327 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2328 | fatal("%s: no cert/certblob", __func__); | ||
2329 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2330 | buffer_len(&key->cert->certblob)); | ||
2331 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2332 | break; | ||
2333 | #endif /* OPENSSL_HAS_ECC */ | ||
2334 | } | ||
2335 | } | ||
2336 | |||
2337 | Key * | ||
2338 | key_private_deserialize(Buffer *blob) | ||
2339 | { | ||
2340 | char *type_name; | ||
2341 | Key *k = NULL; | ||
2342 | u_char *cert; | ||
2343 | u_int len; | ||
2344 | int type; | ||
2345 | #ifdef OPENSSL_HAS_ECC | ||
2346 | char *curve; | ||
2347 | BIGNUM *exponent; | ||
2348 | EC_POINT *q; | ||
2349 | #endif | ||
2350 | |||
2351 | type_name = buffer_get_string(blob, NULL); | ||
2352 | type = key_type_from_name(type_name); | ||
2353 | switch (type) { | ||
2354 | case KEY_DSA: | ||
2355 | k = key_new_private(type); | ||
2356 | buffer_get_bignum2(blob, k->dsa->p); | ||
2357 | buffer_get_bignum2(blob, k->dsa->q); | ||
2358 | buffer_get_bignum2(blob, k->dsa->g); | ||
2359 | buffer_get_bignum2(blob, k->dsa->pub_key); | ||
2360 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2361 | break; | ||
2362 | case KEY_DSA_CERT_V00: | ||
2363 | case KEY_DSA_CERT: | ||
2364 | cert = buffer_get_string(blob, &len); | ||
2365 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2366 | fatal("Certificate parse failed"); | ||
2367 | free(cert); | ||
2368 | key_add_private(k); | ||
2369 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2370 | break; | ||
2371 | #ifdef OPENSSL_HAS_ECC | ||
2372 | case KEY_ECDSA: | ||
2373 | k = key_new_private(type); | ||
2374 | k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); | ||
2375 | curve = buffer_get_string(blob, NULL); | ||
2376 | if (k->ecdsa_nid != key_curve_name_to_nid(curve)) | ||
2377 | fatal("%s: curve names mismatch", __func__); | ||
2378 | free(curve); | ||
2379 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | ||
2380 | if (k->ecdsa == NULL) | ||
2381 | fatal("%s: EC_KEY_new_by_curve_name failed", | ||
2382 | __func__); | ||
2383 | q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); | ||
2384 | if (q == NULL) | ||
2385 | fatal("%s: BN_new failed", __func__); | ||
2386 | if ((exponent = BN_new()) == NULL) | ||
2387 | fatal("%s: BN_new failed", __func__); | ||
2388 | buffer_get_ecpoint(blob, | ||
2389 | EC_KEY_get0_group(k->ecdsa), q); | ||
2390 | buffer_get_bignum2(blob, exponent); | ||
2391 | if (EC_KEY_set_public_key(k->ecdsa, q) != 1) | ||
2392 | fatal("%s: EC_KEY_set_public_key failed", | ||
2393 | __func__); | ||
2394 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2395 | fatal("%s: EC_KEY_set_private_key failed", | ||
2396 | __func__); | ||
2397 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2398 | EC_KEY_get0_public_key(k->ecdsa)) != 0) | ||
2399 | fatal("%s: bad ECDSA public key", __func__); | ||
2400 | if (key_ec_validate_private(k->ecdsa) != 0) | ||
2401 | fatal("%s: bad ECDSA private key", __func__); | ||
2402 | BN_clear_free(exponent); | ||
2403 | EC_POINT_free(q); | ||
2404 | break; | ||
2405 | case KEY_ECDSA_CERT: | ||
2406 | cert = buffer_get_string(blob, &len); | ||
2407 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2408 | fatal("Certificate parse failed"); | ||
2409 | free(cert); | ||
2410 | key_add_private(k); | ||
2411 | if ((exponent = BN_new()) == NULL) | ||
2412 | fatal("%s: BN_new failed", __func__); | ||
2413 | buffer_get_bignum2(blob, exponent); | ||
2414 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2415 | fatal("%s: EC_KEY_set_private_key failed", | ||
2416 | __func__); | ||
2417 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2418 | EC_KEY_get0_public_key(k->ecdsa)) != 0 || | ||
2419 | key_ec_validate_private(k->ecdsa) != 0) | ||
2420 | fatal("%s: bad ECDSA key", __func__); | ||
2421 | BN_clear_free(exponent); | ||
2422 | break; | ||
2423 | #endif | ||
2424 | case KEY_RSA: | ||
2425 | k = key_new_private(type); | ||
2426 | buffer_get_bignum2(blob, k->rsa->n); | ||
2427 | buffer_get_bignum2(blob, k->rsa->e); | ||
2428 | buffer_get_bignum2(blob, k->rsa->d); | ||
2429 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2430 | buffer_get_bignum2(blob, k->rsa->p); | ||
2431 | buffer_get_bignum2(blob, k->rsa->q); | ||
2432 | |||
2433 | /* Generate additional parameters */ | ||
2434 | rsa_generate_additional_parameters(k->rsa); | ||
2435 | break; | ||
2436 | case KEY_RSA_CERT_V00: | ||
2437 | case KEY_RSA_CERT: | ||
2438 | cert = buffer_get_string(blob, &len); | ||
2439 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2440 | fatal("Certificate parse failed"); | ||
2441 | free(cert); | ||
2442 | key_add_private(k); | ||
2443 | buffer_get_bignum2(blob, k->rsa->d); | ||
2444 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2445 | buffer_get_bignum2(blob, k->rsa->p); | ||
2446 | buffer_get_bignum2(blob, k->rsa->q); | ||
2447 | break; | ||
2448 | default: | ||
2449 | free(type_name); | ||
2450 | buffer_clear(blob); | ||
2451 | return NULL; | ||
2452 | } | ||
2453 | free(type_name); | ||
2454 | |||
2455 | /* enable blinding */ | ||
2456 | switch (k->type) { | ||
2457 | case KEY_RSA: | ||
2458 | case KEY_RSA_CERT_V00: | ||
2459 | case KEY_RSA_CERT: | ||
2460 | case KEY_RSA1: | ||
2461 | if (RSA_blinding_on(k->rsa, NULL) != 1) { | ||
2462 | error("%s: RSA_blinding_on failed", __func__); | ||
2463 | key_free(k); | ||
2464 | return NULL; | ||
2465 | } | ||
2466 | break; | ||
2467 | } | ||
2468 | return k; | ||
2469 | } | ||