s2n_pkey.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include "crypto/s2n_pkey.h"
  16. #include <openssl/evp.h>
  17. #include "crypto/s2n_openssl_evp.h"
  18. #include "crypto/s2n_openssl_x509.h"
  19. #include "crypto/s2n_rsa_pss.h"
  20. #include "error/s2n_errno.h"
  21. #include "utils/s2n_result.h"
  22. #include "utils/s2n_safety.h"
  23. #define S2N_MAX_ALLOWED_CERT_TRAILING_BYTES 3
  24. int s2n_pkey_zero_init(struct s2n_pkey *pkey)
  25. {
  26. pkey->pkey = NULL;
  27. pkey->size = NULL;
  28. pkey->sign = NULL;
  29. pkey->verify = NULL;
  30. pkey->encrypt = NULL;
  31. pkey->decrypt = NULL;
  32. pkey->match = NULL;
  33. pkey->free = NULL;
  34. pkey->check_key = NULL;
  35. return 0;
  36. }
  37. int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type)
  38. {
  39. switch (pkey_type) {
  40. case S2N_PKEY_TYPE_RSA:
  41. return s2n_rsa_pkey_init(pkey);
  42. case S2N_PKEY_TYPE_ECDSA:
  43. return s2n_ecdsa_pkey_init(pkey);
  44. case S2N_PKEY_TYPE_RSA_PSS:
  45. return s2n_rsa_pss_pkey_init(pkey);
  46. case S2N_PKEY_TYPE_SENTINEL:
  47. case S2N_PKEY_TYPE_UNKNOWN:
  48. POSIX_BAIL(S2N_ERR_CERT_TYPE_UNSUPPORTED);
  49. }
  50. POSIX_BAIL(S2N_ERR_CERT_TYPE_UNSUPPORTED);
  51. }
  52. int s2n_pkey_check_key_exists(const struct s2n_pkey *pkey)
  53. {
  54. POSIX_ENSURE_REF(pkey->pkey);
  55. POSIX_ENSURE_REF(pkey->check_key);
  56. return pkey->check_key(pkey);
  57. }
  58. S2N_RESULT s2n_pkey_size(const struct s2n_pkey *pkey, uint32_t *size_out)
  59. {
  60. RESULT_ENSURE_REF(pkey);
  61. RESULT_ENSURE_REF(pkey->size);
  62. RESULT_ENSURE_REF(size_out);
  63. RESULT_GUARD(pkey->size(pkey, size_out));
  64. return S2N_RESULT_OK;
  65. }
  66. int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
  67. struct s2n_hash_state *digest, struct s2n_blob *signature)
  68. {
  69. POSIX_ENSURE_REF(pkey->sign);
  70. return pkey->sign(pkey, sig_alg, digest, signature);
  71. }
  72. int s2n_pkey_verify(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
  73. struct s2n_hash_state *digest, struct s2n_blob *signature)
  74. {
  75. POSIX_ENSURE_REF(pkey);
  76. POSIX_ENSURE_REF(pkey->verify);
  77. return pkey->verify(pkey, sig_alg, digest, signature);
  78. }
  79. int s2n_pkey_encrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
  80. {
  81. POSIX_ENSURE_REF(pkey->encrypt);
  82. return pkey->encrypt(pkey, in, out);
  83. }
  84. int s2n_pkey_decrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
  85. {
  86. POSIX_ENSURE_REF(pkey->decrypt);
  87. return pkey->decrypt(pkey, in, out);
  88. }
  89. int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key)
  90. {
  91. POSIX_ENSURE_REF(pub_key->match);
  92. S2N_ERROR_IF(pub_key->match != priv_key->match, S2N_ERR_KEY_MISMATCH);
  93. return pub_key->match(pub_key, priv_key);
  94. }
  95. int s2n_pkey_free(struct s2n_pkey *key)
  96. {
  97. if (key != NULL && key->free != NULL) {
  98. POSIX_GUARD(key->free(key));
  99. }
  100. if (key->pkey != NULL) {
  101. EVP_PKEY_free(key->pkey);
  102. key->pkey = NULL;
  103. }
  104. return S2N_SUCCESS;
  105. }
  106. int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1der, int type_hint)
  107. {
  108. const unsigned char *key_to_parse = asn1der->data;
  109. /* We use "d2i_AutoPrivateKey" instead of "PEM_read_bio_PrivateKey" because
  110. * s2n-tls prefers to perform its own custom PEM parsing. Historically,
  111. * openssl's PEM parsing tended to ignore invalid certificates rather than
  112. * error on them. We prefer to fail early rather than continue without
  113. * the full and correct chain intended by the application.
  114. */
  115. DEFER_CLEANUP(EVP_PKEY *evp_private_key = d2i_AutoPrivateKey(NULL, &key_to_parse, asn1der->size),
  116. EVP_PKEY_free_pointer);
  117. /* We have found cases where d2i_AutoPrivateKey fails to detect the type of
  118. * the key. For example, openssl fails to identify an EC key without the
  119. * optional publicKey field.
  120. *
  121. * If d2i_AutoPrivateKey fails, try once more with the type we parsed from the PEM.
  122. */
  123. if (evp_private_key == NULL) {
  124. evp_private_key = d2i_PrivateKey(type_hint, NULL, &key_to_parse, asn1der->size);
  125. }
  126. POSIX_ENSURE(evp_private_key, S2N_ERR_DECODE_PRIVATE_KEY);
  127. /* If key parsing is successful, d2i_AutoPrivateKey increments *key_to_parse to the byte following the parsed data */
  128. uint32_t parsed_len = key_to_parse - asn1der->data;
  129. if (parsed_len != asn1der->size) {
  130. POSIX_BAIL(S2N_ERR_DECODE_PRIVATE_KEY);
  131. }
  132. /* Initialize s2n_pkey according to key type */
  133. int type = EVP_PKEY_base_id(evp_private_key);
  134. int ret;
  135. switch (type) {
  136. case EVP_PKEY_RSA:
  137. ret = s2n_rsa_pkey_init(priv_key);
  138. if (ret != 0) {
  139. break;
  140. }
  141. ret = s2n_evp_pkey_to_rsa_private_key(&priv_key->key.rsa_key, evp_private_key);
  142. break;
  143. case EVP_PKEY_RSA_PSS:
  144. ret = s2n_rsa_pss_pkey_init(priv_key);
  145. if (ret != 0) {
  146. break;
  147. }
  148. ret = s2n_evp_pkey_to_rsa_pss_private_key(&priv_key->key.rsa_key, evp_private_key);
  149. break;
  150. case EVP_PKEY_EC:
  151. ret = s2n_ecdsa_pkey_init(priv_key);
  152. if (ret != 0) {
  153. break;
  154. }
  155. ret = s2n_evp_pkey_to_ecdsa_private_key(&priv_key->key.ecdsa_key, evp_private_key);
  156. break;
  157. default:
  158. POSIX_BAIL(S2N_ERR_DECODE_PRIVATE_KEY);
  159. }
  160. priv_key->pkey = evp_private_key;
  161. /* Reset to avoid DEFER_CLEANUP freeing our key */
  162. evp_private_key = NULL;
  163. return ret;
  164. }
  165. int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type *pkey_type_out, struct s2n_blob *asn1der)
  166. {
  167. uint8_t *cert_to_parse = asn1der->data;
  168. DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer);
  169. cert = d2i_X509(NULL, (const unsigned char **) (void *) &cert_to_parse, asn1der->size);
  170. S2N_ERROR_IF(cert == NULL, S2N_ERR_DECODE_CERTIFICATE);
  171. /* If cert parsing is successful, d2i_X509 increments *cert_to_parse to the byte following the parsed data */
  172. uint32_t parsed_len = cert_to_parse - asn1der->data;
  173. /* Some TLS clients in the wild send extra trailing bytes after the Certificate.
  174. * Allow this in s2n for backwards compatibility with existing clients. */
  175. uint32_t trailing_bytes = asn1der->size - parsed_len;
  176. POSIX_ENSURE(trailing_bytes <= S2N_MAX_ALLOWED_CERT_TRAILING_BYTES, S2N_ERR_DECODE_CERTIFICATE);
  177. DEFER_CLEANUP(EVP_PKEY *evp_public_key = X509_get_pubkey(cert), EVP_PKEY_free_pointer);
  178. S2N_ERROR_IF(evp_public_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
  179. /* Check for success in decoding certificate according to type */
  180. int type = EVP_PKEY_base_id(evp_public_key);
  181. int ret;
  182. switch (type) {
  183. case EVP_PKEY_RSA:
  184. ret = s2n_rsa_pkey_init(pub_key);
  185. if (ret != 0) {
  186. break;
  187. }
  188. ret = s2n_evp_pkey_to_rsa_public_key(&pub_key->key.rsa_key, evp_public_key);
  189. *pkey_type_out = S2N_PKEY_TYPE_RSA;
  190. break;
  191. case EVP_PKEY_RSA_PSS:
  192. ret = s2n_rsa_pss_pkey_init(pub_key);
  193. if (ret != 0) {
  194. break;
  195. }
  196. ret = s2n_evp_pkey_to_rsa_pss_public_key(&pub_key->key.rsa_key, evp_public_key);
  197. *pkey_type_out = S2N_PKEY_TYPE_RSA_PSS;
  198. break;
  199. case EVP_PKEY_EC:
  200. ret = s2n_ecdsa_pkey_init(pub_key);
  201. if (ret != 0) {
  202. break;
  203. }
  204. ret = s2n_evp_pkey_to_ecdsa_public_key(&pub_key->key.ecdsa_key, evp_public_key);
  205. *pkey_type_out = S2N_PKEY_TYPE_ECDSA;
  206. break;
  207. default:
  208. POSIX_BAIL(S2N_ERR_DECODE_CERTIFICATE);
  209. }
  210. pub_key->pkey = evp_public_key;
  211. /* Reset to avoid DEFER_CLEANUP freeing our key */
  212. evp_public_key = NULL;
  213. return ret;
  214. }