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 /src | |
| 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'
Diffstat (limited to 'src')
| -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 | ||
