diff options
author | William Ahern <william@25thandClement.com> | 2015-12-18 16:03:08 +0800 |
---|---|---|
committer | William Ahern <william@25thandClement.com> | 2015-12-18 16:03:08 +0800 |
commit | 111d688271d05845a9a8411927d543a110f6f4c4 (patch) | |
tree | 3a8a64a0753c78da9b320b82e24e774e5fe71a1e | |
parent | 67187d3b796abef2836e2425c0c28f1bb48e5233 (diff) | |
parent | 7d6ee936398acc1846671fd9c94ecfacfd953c82 (diff) | |
download | luaossl-111d688271d05845a9a8411927d543a110f6f4c4.tar.gz luaossl-111d688271d05845a9a8411927d543a110f6f4c4.tar.bz2 luaossl-111d688271d05845a9a8411927d543a110f6f4c4.zip |
Merge branch 'daurnimator-36-private-key-inspection'
-rw-r--r-- | src/openssl.c | 260 |
1 files changed, 258 insertions, 2 deletions
diff --git a/src/openssl.c b/src/openssl.c index 01bf2c8..84a0155 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -1558,6 +1558,16 @@ static BIGNUM *bn_push(lua_State *L) { | |||
1558 | } /* bn_push() */ | 1558 | } /* bn_push() */ |
1559 | 1559 | ||
1560 | 1560 | ||
1561 | static BIGNUM *bn_dup(lua_State *L, const BIGNUM *src) { | ||
1562 | BIGNUM **ud = prepsimple(L, BIGNUM_CLASS); | ||
1563 | |||
1564 | if (!(*ud = BN_dup(src))) | ||
1565 | auxL_error(L, auxL_EOPENSSL, "bignum"); | ||
1566 | |||
1567 | return *ud; | ||
1568 | } /* bn_dup() */ | ||
1569 | |||
1570 | |||
1561 | #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) | 1571 | #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) |
1562 | #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0) | 1572 | #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0) |
1563 | 1573 | ||
@@ -2151,7 +2161,7 @@ creat: | |||
2151 | } | 2161 | } |
2152 | #endif | 2162 | #endif |
2153 | default: | 2163 | default: |
2154 | return luaL_error(L, "%d: unknown EVP base type (%d)", EVP_PKEY_type(type), type); | 2164 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_type(type)); |
2155 | } /* switch() */ | 2165 | } /* switch() */ |
2156 | } else if (lua_isstring(L, 1)) { | 2166 | } else if (lua_isstring(L, 1)) { |
2157 | int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); | 2167 | int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); |
@@ -2478,7 +2488,7 @@ static int pk_toPEM(lua_State *L) { | |||
2478 | } | 2488 | } |
2479 | #endif | 2489 | #endif |
2480 | default: | 2490 | default: |
2481 | return luaL_error(L, "%d: unknown EVP base type", EVP_PKEY_type(key->type)); | 2491 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_type(key->type)); |
2482 | } | 2492 | } |
2483 | 2493 | ||
2484 | lua_pushlstring(L, pem, len); | 2494 | lua_pushlstring(L, pem, len); |
@@ -2498,6 +2508,251 @@ static int pk_toPEM(lua_State *L) { | |||
2498 | } /* pk_toPEM() */ | 2508 | } /* pk_toPEM() */ |
2499 | 2509 | ||
2500 | 2510 | ||
2511 | enum pk_param { | ||
2512 | #define PK_RSA_OPTLIST { "n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp", NULL } | ||
2513 | #define PK_RSA_OPTOFFSET PK_RSA_N | ||
2514 | PK_RSA_N = 1, | ||
2515 | PK_RSA_E, | ||
2516 | PK_RSA_D, | ||
2517 | PK_RSA_P, | ||
2518 | PK_RSA_Q, | ||
2519 | PK_RSA_DMP1, | ||
2520 | PK_RSA_DMQ1, | ||
2521 | PK_RSA_IQMP, | ||
2522 | |||
2523 | #define PK_DSA_OPTLIST { "p", "q", "g", "pub_key", "priv_key", NULL } | ||
2524 | #define PK_DSA_OPTOFFSET PK_DSA_P | ||
2525 | PK_DSA_P, | ||
2526 | PK_DSA_Q, | ||
2527 | PK_DSA_G, | ||
2528 | PK_DSA_PUB_KEY, | ||
2529 | PK_DSA_PRIV_KEY, | ||
2530 | |||
2531 | #define PK_DH_OPTLIST { "p", "g", "pub_key", "priv_key", NULL } | ||
2532 | #define PK_DH_OPTOFFSET PK_DH_P | ||
2533 | PK_DH_P, | ||
2534 | PK_DH_G, | ||
2535 | PK_DH_PUB_KEY, | ||
2536 | PK_DH_PRIV_KEY, | ||
2537 | |||
2538 | #define PK_EC_OPTLIST { "pub_key", "priv_key", NULL } | ||
2539 | #define PK_EC_OPTOFFSET PK_EC_PUB_KEY | ||
2540 | PK_EC_PUB_KEY, | ||
2541 | PK_EC_PRIV_KEY, | ||
2542 | }; /* enum pk_param */ | ||
2543 | |||
2544 | static const char *const pk_rsa_optlist[] = PK_RSA_OPTLIST; | ||
2545 | static const char *const pk_dsa_optlist[] = PK_DSA_OPTLIST; | ||
2546 | static const char *const pk_dh_optlist[] = PK_DH_OPTLIST; | ||
2547 | static const char *const pk_ec_optlist[] = PK_EC_OPTLIST; | ||
2548 | |||
2549 | static int pk_checkparam(lua_State *L, int type, int index) { | ||
2550 | switch (type) { | ||
2551 | case EVP_PKEY_RSA: | ||
2552 | return luaL_checkoption(L, index, NULL, pk_rsa_optlist) + PK_RSA_OPTOFFSET; | ||
2553 | case EVP_PKEY_DSA: | ||
2554 | return luaL_checkoption(L, index, NULL, pk_dsa_optlist) + PK_DSA_OPTOFFSET; | ||
2555 | case EVP_PKEY_DH: | ||
2556 | return luaL_checkoption(L, index, NULL, pk_dh_optlist) + PK_DH_OPTOFFSET; | ||
2557 | case EVP_PKEY_EC: | ||
2558 | return luaL_checkoption(L, index, NULL, pk_ec_optlist) + PK_EC_OPTOFFSET; | ||
2559 | default: | ||
2560 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", type); | ||
2561 | } | ||
2562 | } /* pk_checkparam() */ | ||
2563 | |||
2564 | static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { | ||
2565 | union { | ||
2566 | RSA *rsa; | ||
2567 | DH *dh; | ||
2568 | DSA *dsa; | ||
2569 | EC_KEY *ec; | ||
2570 | } key = { _key }; | ||
2571 | |||
2572 | switch (which) { | ||
2573 | case PK_RSA_N: | ||
2574 | /* RSA public modulus n */ | ||
2575 | bn_dup(L, key.rsa->n); | ||
2576 | |||
2577 | break; | ||
2578 | case PK_RSA_E: | ||
2579 | /* RSA public exponent e */ | ||
2580 | bn_dup(L, key.rsa->e); | ||
2581 | |||
2582 | break; | ||
2583 | case PK_RSA_D: | ||
2584 | /* RSA secret exponent d */ | ||
2585 | bn_dup(L, key.rsa->d); | ||
2586 | |||
2587 | break; | ||
2588 | case PK_RSA_P: | ||
2589 | /* RSA secret prime p */ | ||
2590 | bn_dup(L, key.rsa->p); | ||
2591 | |||
2592 | break; | ||
2593 | case PK_RSA_Q: | ||
2594 | /* RSA secret prime q with p < q */ | ||
2595 | bn_dup(L, key.rsa->q); | ||
2596 | |||
2597 | break; | ||
2598 | case PK_RSA_DMP1: | ||
2599 | /* exponent1 */ | ||
2600 | bn_dup(L, key.rsa->dmp1); | ||
2601 | |||
2602 | break; | ||
2603 | case PK_RSA_DMQ1: | ||
2604 | /* exponent2 */ | ||
2605 | bn_dup(L, key.rsa->dmq1); | ||
2606 | |||
2607 | break; | ||
2608 | case PK_RSA_IQMP: | ||
2609 | /* coefficient */ | ||
2610 | bn_dup(L, key.rsa->iqmp); | ||
2611 | |||
2612 | break; | ||
2613 | case PK_DSA_P: | ||
2614 | bn_dup(L, key.dsa->p); | ||
2615 | |||
2616 | break; | ||
2617 | case PK_DSA_Q: | ||
2618 | bn_dup(L, key.dsa->q); | ||
2619 | |||
2620 | break; | ||
2621 | case PK_DSA_G: | ||
2622 | bn_dup(L, key.dsa->g); | ||
2623 | |||
2624 | break; | ||
2625 | case PK_DSA_PUB_KEY: | ||
2626 | bn_dup(L, key.dsa->pub_key); | ||
2627 | |||
2628 | break; | ||
2629 | case PK_DSA_PRIV_KEY: | ||
2630 | bn_dup(L, key.dsa->priv_key); | ||
2631 | |||
2632 | break; | ||
2633 | case PK_DH_P: | ||
2634 | bn_dup(L, key.dh->p); | ||
2635 | |||
2636 | break; | ||
2637 | case PK_DH_G: | ||
2638 | bn_dup(L, key.dh->g); | ||
2639 | |||
2640 | break; | ||
2641 | case PK_DH_PUB_KEY: | ||
2642 | bn_dup(L, key.dh->pub_key); | ||
2643 | |||
2644 | break; | ||
2645 | case PK_DH_PRIV_KEY: | ||
2646 | bn_dup(L, key.dh->priv_key); | ||
2647 | |||
2648 | break; | ||
2649 | case PK_EC_PUB_KEY: { | ||
2650 | const EC_GROUP *group; | ||
2651 | const EC_POINT *public_key; | ||
2652 | |||
2653 | if (!(group = EC_KEY_get0_group(key.ec)) || !(public_key = EC_KEY_get0_public_key(key.ec))) | ||
2654 | goto sslerr; | ||
2655 | bn_dup(L, EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); | ||
2656 | |||
2657 | break; | ||
2658 | } | ||
2659 | case PK_EC_PRIV_KEY: | ||
2660 | bn_dup(L, EC_KEY_get0_private_key(key.ec)); | ||
2661 | |||
2662 | break; | ||
2663 | default: | ||
2664 | luaL_error(L, "%d: invalid EVP_PKEY parameter", which); | ||
2665 | } | ||
2666 | |||
2667 | return; | ||
2668 | sslerr: | ||
2669 | auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); | ||
2670 | |||
2671 | return; | ||
2672 | } /* pk_pushparam() */ | ||
2673 | |||
2674 | |||
2675 | static int pk_getParameters(lua_State *L) { | ||
2676 | EVP_PKEY *_key = checksimple(L, 1, PKEY_CLASS); | ||
2677 | int type = EVP_PKEY_base_id(_key); | ||
2678 | void *key; | ||
2679 | int otop, index, tindex; | ||
2680 | |||
2681 | if (!(key = EVP_PKEY_get0(_key))) | ||
2682 | goto sslerr; | ||
2683 | |||
2684 | if (lua_isnoneornil(L, 2)) { | ||
2685 | const char *const *optlist; | ||
2686 | const char *const *opt; | ||
2687 | |||
2688 | switch (type) { | ||
2689 | case EVP_PKEY_RSA: | ||
2690 | optlist = pk_rsa_optlist; | ||
2691 | luaL_checkstack(L, countof(pk_rsa_optlist), ""); | ||
2692 | |||
2693 | break; | ||
2694 | case EVP_PKEY_DSA: | ||
2695 | optlist = pk_dsa_optlist; | ||
2696 | luaL_checkstack(L, countof(pk_dsa_optlist), ""); | ||
2697 | |||
2698 | break; | ||
2699 | case EVP_PKEY_DH: | ||
2700 | optlist = pk_dh_optlist; | ||
2701 | luaL_checkstack(L, countof(pk_dh_optlist), ""); | ||
2702 | |||
2703 | break; | ||
2704 | case EVP_PKEY_EC: | ||
2705 | optlist = pk_ec_optlist; | ||
2706 | luaL_checkstack(L, countof(pk_ec_optlist), ""); | ||
2707 | |||
2708 | break; | ||
2709 | default: | ||
2710 | return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key)); | ||
2711 | } | ||
2712 | |||
2713 | /* | ||
2714 | * Use special "{" parameter to tell loop to push table. | ||
2715 | * Subsequent parameters will be assigned as fields. | ||
2716 | * | ||
2717 | * NOTE: optlist arrays are NULL-terminated. luaL_checkstack() | ||
2718 | * calls above left room for "{". | ||
2719 | */ | ||
2720 | lua_pushstring(L, "{"); | ||
2721 | |||
2722 | for (opt = optlist; *opt; opt++) { | ||
2723 | lua_pushstring(L, *opt); | ||
2724 | } | ||
2725 | } | ||
2726 | |||
2727 | otop = lua_gettop(L); | ||
2728 | |||
2729 | /* provide space for results and working area */ | ||
2730 | luaL_checkstack(L, (otop - 1) + LUA_MINSTACK, ""); | ||
2731 | |||
2732 | /* no table index, yet */ | ||
2733 | tindex = 0; | ||
2734 | |||
2735 | for (index = 2; index <= otop; index++) { | ||
2736 | const char *opt = luaL_checkstring(L, index); | ||
2737 | |||
2738 | if (*opt == '{') { | ||
2739 | lua_newtable(L); | ||
2740 | tindex = lua_gettop(L); | ||
2741 | } else { | ||
2742 | pk_pushparam(L, key, pk_checkparam(L, type, index)); | ||
2743 | |||
2744 | if (tindex) { | ||
2745 | lua_setfield(L, tindex, opt); | ||
2746 | } | ||
2747 | } | ||
2748 | } | ||
2749 | |||
2750 | return lua_gettop(L) - otop; | ||
2751 | sslerr: | ||
2752 | return auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); | ||
2753 | } /* pk_getParameters() */ | ||
2754 | |||
2755 | |||
2501 | static int pk__tostring(lua_State *L) { | 2756 | static int pk__tostring(lua_State *L) { |
2502 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 2757 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); |
2503 | int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); | 2758 | int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); |
@@ -2543,6 +2798,7 @@ static const luaL_Reg pk_methods[] = { | |||
2543 | { "sign", &pk_sign }, | 2798 | { "sign", &pk_sign }, |
2544 | { "verify", &pk_verify }, | 2799 | { "verify", &pk_verify }, |
2545 | { "toPEM", &pk_toPEM }, | 2800 | { "toPEM", &pk_toPEM }, |
2801 | { "getParameters", &pk_getParameters }, | ||
2546 | { NULL, NULL }, | 2802 | { NULL, NULL }, |
2547 | }; | 2803 | }; |
2548 | 2804 | ||