1
0

rsa.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
  2. /*
  3. * Copyright 2016 Red Hat, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "misc.h"
  18. #include "../hooks.h"
  19. #include <jose/openssl.h>
  20. #include <string.h>
  21. /* The following functions are from OpenSSL 3 code base:
  22. * - bn_is_three()
  23. * - check_public_exponent() is ossl_rsa_check_public_exponent(), with
  24. * a minor change -- no FIPS check for allowing RSA_3. */
  25. static int bn_is_three(const BIGNUM *bn)
  26. {
  27. BIGNUM *num = BN_dup(bn);
  28. int ret = (num != NULL && BN_sub_word(num, 3) && BN_is_zero(num));
  29. BN_free(num);
  30. return ret;
  31. }
  32. /* Check exponent is odd, and has a bitlen ranging from [17..256]
  33. * In practice, it allows odd integers greater than or equal to 65537. 3 is
  34. * also allowed, for legacy purposes. */
  35. static int check_public_exponent(const BIGNUM* e)
  36. {
  37. int bitlen;
  38. /* In OpenSSL 3, RSA_3 is allowed in non-FIPS mode only, for
  39. * legacy purposes. */
  40. if (bn_is_three(e)) {
  41. return 1;
  42. }
  43. bitlen = BN_num_bits(e);
  44. return (BN_is_odd(e) && bitlen > 16 && bitlen < 257);
  45. }
  46. static RSA *
  47. mkrsa(const json_t *jwk)
  48. {
  49. openssl_auto(BIGNUM) *bn = NULL;
  50. json_auto_t *exp = NULL;
  51. RSA *key = NULL;
  52. int bits = 2048;
  53. if (json_unpack((json_t *) jwk, "{s?i,s?O}",
  54. "bits", &bits, "e", &exp) == -1)
  55. return NULL;
  56. if (bits < 2048)
  57. return NULL;
  58. if (!exp)
  59. exp = json_integer(65537);
  60. switch (exp ? exp->type : JSON_NULL) {
  61. case JSON_STRING:
  62. bn = bn_decode_json(exp);
  63. if (!bn)
  64. return NULL;
  65. break;
  66. case JSON_INTEGER:
  67. bn = BN_new();
  68. if (!bn)
  69. return NULL;
  70. if (BN_set_word(bn, json_integer_value(exp)) <= 0)
  71. return NULL;
  72. break;
  73. default:
  74. break;
  75. }
  76. if (!check_public_exponent(bn)) {
  77. return NULL;
  78. }
  79. key = RSA_new();
  80. if (!key)
  81. return NULL;
  82. bits = RSA_generate_key_ex(key, bits, bn, NULL);
  83. if (bits <= 0) {
  84. RSA_free(key);
  85. key = NULL;
  86. }
  87. return key;
  88. }
  89. static bool
  90. jwk_make_handles(jose_cfg_t *cfg, const json_t *jwk)
  91. {
  92. const char *kty = NULL;
  93. if (json_unpack((json_t *) jwk, "{s:s}", "kty", &kty) == -1)
  94. return false;
  95. return strcmp(kty, "RSA") == 0;
  96. }
  97. static bool
  98. jwk_make_execute(jose_cfg_t *cfg, json_t *jwk)
  99. {
  100. json_auto_t *key = NULL;
  101. RSA *rsa = NULL;
  102. if (!jwk_make_handles(cfg, jwk))
  103. return false;
  104. rsa = mkrsa(jwk);
  105. if (!rsa)
  106. return false;
  107. key = jose_openssl_jwk_from_RSA(cfg, rsa);
  108. RSA_free(rsa);
  109. if (!key)
  110. return false;
  111. if (json_object_get(jwk, "bits") && json_object_del(jwk, "bits") < 0)
  112. return false;
  113. if (json_object_get(jwk, "e") && json_object_del(jwk, "e") < 0)
  114. return false;
  115. /* The "oth" parameter is optional. */
  116. copy_val(key, jwk, "oth");
  117. return copy_val(key, jwk, "n", "e", "p", "d", "q", "dp", "dq", "qi", NULL);
  118. }
  119. static void __attribute__((constructor))
  120. constructor(void)
  121. {
  122. static jose_hook_jwk_t jwk = {
  123. .kind = JOSE_HOOK_JWK_KIND_MAKE,
  124. .make.handles = jwk_make_handles,
  125. .make.execute = jwk_make_execute
  126. };
  127. jose_hook_jwk_push(&jwk);
  128. }