diff options
| author | William Ahern <william@25thandClement.com> | 2015-12-18 16:02:25 +0800 |
|---|---|---|
| committer | William Ahern <william@25thandClement.com> | 2015-12-18 16:02:25 +0800 |
| commit | 7d6ee936398acc1846671fd9c94ecfacfd953c82 (patch) | |
| tree | 3a8a64a0753c78da9b320b82e24e774e5fe71a1e | |
| parent | 73b1a614759da1bc064d3b6cfff221981b04d8b8 (diff) | |
| download | luaossl-7d6ee936398acc1846671fd9c94ecfacfd953c82.tar.gz luaossl-7d6ee936398acc1846671fd9c94ecfacfd953c82.tar.bz2 luaossl-7d6ee936398acc1846671fd9c94ecfacfd953c82.zip | |
return value list instead of table if parameter names specified explicitly
| -rw-r--r-- | src/openssl.c | 272 |
1 files changed, 208 insertions, 64 deletions
diff --git a/src/openssl.c b/src/openssl.c index 5bc42ab..84a0155 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
| @@ -2161,7 +2161,7 @@ creat: | |||
| 2161 | } | 2161 | } |
| 2162 | #endif | 2162 | #endif |
| 2163 | default: | 2163 | default: |
| 2164 | 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)); |
| 2165 | } /* switch() */ | 2165 | } /* switch() */ |
| 2166 | } else if (lua_isstring(L, 1)) { | 2166 | } else if (lua_isstring(L, 1)) { |
| 2167 | int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); | 2167 | int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); |
| @@ -2488,7 +2488,7 @@ static int pk_toPEM(lua_State *L) { | |||
| 2488 | } | 2488 | } |
| 2489 | #endif | 2489 | #endif |
| 2490 | default: | 2490 | default: |
| 2491 | 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)); |
| 2492 | } | 2492 | } |
| 2493 | 2493 | ||
| 2494 | lua_pushlstring(L, pem, len); | 2494 | lua_pushlstring(L, pem, len); |
| @@ -2508,102 +2508,246 @@ static int pk_toPEM(lua_State *L) { | |||
| 2508 | } /* pk_toPEM() */ | 2508 | } /* pk_toPEM() */ |
| 2509 | 2509 | ||
| 2510 | 2510 | ||
| 2511 | static int pk_getParameters(lua_State *L) { | 2511 | enum pk_param { |
| 2512 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 2512 | #define PK_RSA_OPTLIST { "n", "e", "d", "p", "q", "dmp1", "dmq1", "iqmp", NULL } |
| 2513 | _Bool public_only = lua_toboolean(L, 2); | 2513 | #define PK_RSA_OPTOFFSET PK_RSA_N |
| 2514 | void *tmp; | 2514 | PK_RSA_N = 1, |
| 2515 | 2515 | PK_RSA_E, | |
| 2516 | if (!(tmp = EVP_PKEY_get0(key))) | 2516 | PK_RSA_D, |
| 2517 | goto sslerr; | 2517 | PK_RSA_P, |
| 2518 | 2518 | PK_RSA_Q, | |
| 2519 | lua_newtable(L); | 2519 | PK_RSA_DMP1, |
| 2520 | 2520 | PK_RSA_DMQ1, | |
| 2521 | switch (EVP_PKEY_base_id(key)) { | 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) { | ||
| 2522 | case EVP_PKEY_RSA: | 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: | ||
| 2523 | /* RSA public modulus n */ | 2574 | /* RSA public modulus n */ |
| 2524 | bn_dup(L, ((RSA*)tmp)->n); | 2575 | bn_dup(L, key.rsa->n); |
| 2525 | lua_setfield(L, -2, "n"); | ||
| 2526 | 2576 | ||
| 2577 | break; | ||
| 2578 | case PK_RSA_E: | ||
| 2527 | /* RSA public exponent e */ | 2579 | /* RSA public exponent e */ |
| 2528 | bn_dup(L, ((RSA*)tmp)->e); | 2580 | bn_dup(L, key.rsa->e); |
| 2529 | lua_setfield(L, -2, "e"); | ||
| 2530 | |||
| 2531 | if (public_only) | ||
| 2532 | break; | ||
| 2533 | 2581 | ||
| 2582 | break; | ||
| 2583 | case PK_RSA_D: | ||
| 2534 | /* RSA secret exponent d */ | 2584 | /* RSA secret exponent d */ |
| 2535 | bn_dup(L, ((RSA*)tmp)->d); | 2585 | bn_dup(L, key.rsa->d); |
| 2536 | lua_setfield(L, -2, "d"); | ||
| 2537 | 2586 | ||
| 2587 | break; | ||
| 2588 | case PK_RSA_P: | ||
| 2538 | /* RSA secret prime p */ | 2589 | /* RSA secret prime p */ |
| 2539 | bn_dup(L, ((RSA*)tmp)->p); | 2590 | bn_dup(L, key.rsa->p); |
| 2540 | lua_setfield(L, -2, "p"); | ||
| 2541 | 2591 | ||
| 2592 | break; | ||
| 2593 | case PK_RSA_Q: | ||
| 2542 | /* RSA secret prime q with p < q */ | 2594 | /* RSA secret prime q with p < q */ |
| 2543 | bn_dup(L, ((RSA*)tmp)->q); | 2595 | bn_dup(L, key.rsa->q); |
| 2544 | lua_setfield(L, -2, "q"); | ||
| 2545 | 2596 | ||
| 2597 | break; | ||
| 2598 | case PK_RSA_DMP1: | ||
| 2546 | /* exponent1 */ | 2599 | /* exponent1 */ |
| 2547 | bn_dup(L, ((RSA*)tmp)->dmp1); | 2600 | bn_dup(L, key.rsa->dmp1); |
| 2548 | lua_setfield(L, -2, "dmp1"); | ||
| 2549 | 2601 | ||
| 2602 | break; | ||
| 2603 | case PK_RSA_DMQ1: | ||
| 2550 | /* exponent2 */ | 2604 | /* exponent2 */ |
| 2551 | bn_dup(L, ((RSA*)tmp)->dmq1); | 2605 | bn_dup(L, key.rsa->dmq1); |
| 2552 | lua_setfield(L, -2, "dmq1"); | ||
| 2553 | 2606 | ||
| 2607 | break; | ||
| 2608 | case PK_RSA_IQMP: | ||
| 2554 | /* coefficient */ | 2609 | /* coefficient */ |
| 2555 | bn_dup(L, ((RSA*)tmp)->iqmp); | 2610 | bn_dup(L, key.rsa->iqmp); |
| 2556 | lua_setfield(L, -2, "iqmp"); | ||
| 2557 | 2611 | ||
| 2558 | break; | 2612 | break; |
| 2559 | case EVP_PKEY_DH: | 2613 | case PK_DSA_P: |
| 2560 | /* prime */ | 2614 | bn_dup(L, key.dsa->p); |
| 2561 | bn_dup(L, ((DH*)tmp)->p); | ||
| 2562 | lua_setfield(L, -2, "p"); | ||
| 2563 | 2615 | ||
| 2564 | /* generator */ | 2616 | break; |
| 2565 | bn_dup(L, ((DH*)tmp)->g); | 2617 | case PK_DSA_Q: |
| 2566 | lua_setfield(L, -2, "g"); | 2618 | bn_dup(L, key.dsa->q); |
| 2567 | 2619 | ||
| 2568 | /* pub_key */ | 2620 | break; |
| 2569 | bn_dup(L, ((DH*)tmp)->pub_key); | 2621 | case PK_DSA_G: |
| 2570 | lua_setfield(L, -2, "pub_key"); | 2622 | bn_dup(L, key.dsa->g); |
| 2571 | 2623 | ||
| 2572 | if (public_only) | 2624 | break; |
| 2573 | break; | 2625 | case PK_DSA_PUB_KEY: |
| 2626 | bn_dup(L, key.dsa->pub_key); | ||
| 2574 | 2627 | ||
| 2575 | /* priv_key */ | 2628 | break; |
| 2576 | bn_dup(L, ((DH*)tmp)->priv_key); | 2629 | case PK_DSA_PRIV_KEY: |
| 2577 | lua_setfield(L, -2, "priv_key"); | 2630 | bn_dup(L, key.dsa->priv_key); |
| 2578 | 2631 | ||
| 2579 | break; | 2632 | break; |
| 2580 | #ifndef OPENSSL_NO_EC | 2633 | case PK_DH_P: |
| 2581 | case EVP_PKEY_EC: { | 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: { | ||
| 2582 | const EC_GROUP *group; | 2650 | const EC_GROUP *group; |
| 2583 | const EC_POINT *public_key; | 2651 | const EC_POINT *public_key; |
| 2584 | 2652 | ||
| 2585 | /* pub_key */ | 2653 | if (!(group = EC_KEY_get0_group(key.ec)) || !(public_key = EC_KEY_get0_public_key(key.ec))) |
| 2586 | if (!(group = EC_KEY_get0_group(tmp)) || !(public_key = EC_KEY_get0_public_key(tmp))) | ||
| 2587 | goto sslerr; | 2654 | goto sslerr; |
| 2588 | bn_dup(L, EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(tmp), NULL, getctx(L))); | 2655 | bn_dup(L, EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); |
| 2589 | lua_setfield(L, -2, "pub_key"); | 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), ""); | ||
| 2590 | 2692 | ||
| 2591 | if (public_only) | ||
| 2592 | break; | 2693 | break; |
| 2694 | case EVP_PKEY_DSA: | ||
| 2695 | optlist = pk_dsa_optlist; | ||
| 2696 | luaL_checkstack(L, countof(pk_dsa_optlist), ""); | ||
| 2593 | 2697 | ||
| 2594 | /* priv_key */ | 2698 | break; |
| 2595 | bn_dup(L, EC_KEY_get0_private_key(tmp)); | 2699 | case EVP_PKEY_DH: |
| 2596 | goto sslerr; | 2700 | optlist = pk_dh_optlist; |
| 2597 | lua_setfield(L, -2, "priv_key"); | 2701 | luaL_checkstack(L, countof(pk_dh_optlist), ""); |
| 2598 | 2702 | ||
| 2599 | break; | 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 | } | ||
| 2600 | } | 2725 | } |
| 2601 | #endif | ||
| 2602 | default: | ||
| 2603 | return luaL_error(L, "%d: unsupported EVP base type", EVP_PKEY_base_id(key)); | ||
| 2604 | } /* switch() */ | ||
| 2605 | 2726 | ||
| 2606 | return 1; | 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; | ||
| 2607 | sslerr: | 2751 | sslerr: |
| 2608 | return auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); | 2752 | return auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); |
| 2609 | } /* pk_getParameters() */ | 2753 | } /* pk_getParameters() */ |
