您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

386 行
11 KiB

  1. /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  2. * project 2006.
  3. */
  4. /* ====================================================================
  5. * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. All advertising materials mentioning features or use of this
  20. * software must display the following acknowledgment:
  21. * "This product includes software developed by the OpenSSL Project
  22. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  23. *
  24. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  25. * endorse or promote products derived from this software without
  26. * prior written permission. For written permission, please contact
  27. * licensing@OpenSSL.org.
  28. *
  29. * 5. Products derived from this software may not be called "OpenSSL"
  30. * nor may "OpenSSL" appear in their names without prior written
  31. * permission of the OpenSSL Project.
  32. *
  33. * 6. Redistributions of any form whatsoever must retain the following
  34. * acknowledgment:
  35. * "This product includes software developed by the OpenSSL Project
  36. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  37. *
  38. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  39. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  40. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  41. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  42. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  47. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  48. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  49. * OF THE POSSIBILITY OF SUCH DAMAGE.
  50. * ====================================================================
  51. *
  52. * This product includes cryptographic software written by Eric Young
  53. * (eay@cryptsoft.com). This product includes software written by Tim
  54. * Hudson (tjh@cryptsoft.com). */
  55. #include <openssl/x509.h>
  56. #include <assert.h>
  57. #include <openssl/asn1.h>
  58. #include <openssl/asn1t.h>
  59. #include <openssl/bio.h>
  60. #include <openssl/evp.h>
  61. #include <openssl/err.h>
  62. #include <openssl/obj.h>
  63. #include "internal.h"
  64. ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
  65. ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
  66. ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
  67. ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
  68. ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3),
  69. } ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
  70. IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
  71. /* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
  72. static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
  73. if (alg == NULL || alg->parameter == NULL ||
  74. OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
  75. alg->parameter->type != V_ASN1_SEQUENCE) {
  76. return NULL;
  77. }
  78. const uint8_t *p = alg->parameter->value.sequence->data;
  79. int plen = alg->parameter->value.sequence->length;
  80. return d2i_X509_ALGOR(NULL, &p, plen);
  81. }
  82. static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
  83. X509_ALGOR **pmaskHash) {
  84. *pmaskHash = NULL;
  85. if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) {
  86. return NULL;
  87. }
  88. const uint8_t *p = alg->parameter->value.sequence->data;
  89. int plen = alg->parameter->value.sequence->length;
  90. RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen);
  91. if (pss == NULL) {
  92. return NULL;
  93. }
  94. *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
  95. return pss;
  96. }
  97. /* allocate and set algorithm ID from EVP_MD, default SHA1 */
  98. static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) {
  99. if (EVP_MD_type(md) == NID_sha1) {
  100. return 1;
  101. }
  102. *palg = X509_ALGOR_new();
  103. if (*palg == NULL) {
  104. return 0;
  105. }
  106. X509_ALGOR_set_md(*palg, md);
  107. return 1;
  108. }
  109. /* Allocate and set MGF1 algorithm ID from EVP_MD */
  110. static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
  111. X509_ALGOR *algtmp = NULL;
  112. ASN1_STRING *stmp = NULL;
  113. *palg = NULL;
  114. if (EVP_MD_type(mgf1md) == NID_sha1) {
  115. return 1;
  116. }
  117. /* need to embed algorithm ID inside another */
  118. if (!rsa_md_to_algor(&algtmp, mgf1md) ||
  119. !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) {
  120. goto err;
  121. }
  122. *palg = X509_ALGOR_new();
  123. if (!*palg) {
  124. goto err;
  125. }
  126. X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
  127. stmp = NULL;
  128. err:
  129. ASN1_STRING_free(stmp);
  130. X509_ALGOR_free(algtmp);
  131. if (*palg) {
  132. return 1;
  133. }
  134. return 0;
  135. }
  136. /* convert algorithm ID to EVP_MD, default SHA1 */
  137. static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
  138. const EVP_MD *md;
  139. if (!alg) {
  140. return EVP_sha1();
  141. }
  142. md = EVP_get_digestbyobj(alg->algorithm);
  143. if (md == NULL) {
  144. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  145. }
  146. return md;
  147. }
  148. /* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
  149. static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
  150. const EVP_MD *md;
  151. if (!alg) {
  152. return EVP_sha1();
  153. }
  154. /* Check mask and lookup mask hash algorithm */
  155. if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
  156. maskHash == NULL) {
  157. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  158. return NULL;
  159. }
  160. md = EVP_get_digestbyobj(maskHash->algorithm);
  161. if (md == NULL) {
  162. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  163. return NULL;
  164. }
  165. return md;
  166. }
  167. int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
  168. const EVP_MD *sigmd, *mgf1md;
  169. int saltlen;
  170. if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) ||
  171. !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) ||
  172. !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) {
  173. return 0;
  174. }
  175. EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
  176. if (saltlen == -1) {
  177. saltlen = EVP_MD_size(sigmd);
  178. } else if (saltlen == -2) {
  179. saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
  180. if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
  181. saltlen--;
  182. }
  183. } else {
  184. return 0;
  185. }
  186. int ret = 0;
  187. ASN1_STRING *os = NULL;
  188. RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();
  189. if (!pss) {
  190. goto err;
  191. }
  192. if (saltlen != 20) {
  193. pss->saltLength = ASN1_INTEGER_new();
  194. if (!pss->saltLength ||
  195. !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
  196. goto err;
  197. }
  198. }
  199. if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
  200. !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
  201. goto err;
  202. }
  203. /* Finally create string with pss parameter encoding. */
  204. if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
  205. goto err;
  206. }
  207. X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
  208. os = NULL;
  209. ret = 1;
  210. err:
  211. RSA_PSS_PARAMS_free(pss);
  212. ASN1_STRING_free(os);
  213. return ret;
  214. }
  215. int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
  216. assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
  217. /* Decode PSS parameters */
  218. int ret = 0;
  219. X509_ALGOR *maskHash;
  220. RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
  221. if (pss == NULL) {
  222. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  223. goto err;
  224. }
  225. const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
  226. const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm);
  227. if (mgf1md == NULL || md == NULL) {
  228. goto err;
  229. }
  230. int saltlen = 20;
  231. if (pss->saltLength != NULL) {
  232. saltlen = ASN1_INTEGER_get(pss->saltLength);
  233. /* Could perform more salt length sanity checks but the main
  234. * RSA routines will trap other invalid values anyway. */
  235. if (saltlen < 0) {
  236. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  237. goto err;
  238. }
  239. }
  240. /* low-level routines support only trailer field 0xbc (value 1)
  241. * and PKCS#1 says we should reject any other value anyway. */
  242. if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) {
  243. OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
  244. goto err;
  245. }
  246. EVP_PKEY_CTX *pctx;
  247. if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) ||
  248. !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
  249. !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) ||
  250. !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) {
  251. goto err;
  252. }
  253. ret = 1;
  254. err:
  255. RSA_PSS_PARAMS_free(pss);
  256. X509_ALGOR_free(maskHash);
  257. return ret;
  258. }
  259. int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent,
  260. ASN1_PCTX *pctx) {
  261. assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss);
  262. int rv = 0;
  263. X509_ALGOR *maskHash;
  264. RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash);
  265. if (!pss) {
  266. if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) {
  267. goto err;
  268. }
  269. rv = 1;
  270. goto err;
  271. }
  272. if (BIO_puts(bp, "\n") <= 0 ||
  273. !BIO_indent(bp, indent, 128) ||
  274. BIO_puts(bp, "Hash Algorithm: ") <= 0) {
  275. goto err;
  276. }
  277. if (pss->hashAlgorithm) {
  278. if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) {
  279. goto err;
  280. }
  281. } else if (BIO_puts(bp, "sha1 (default)") <= 0) {
  282. goto err;
  283. }
  284. if (BIO_puts(bp, "\n") <= 0 ||
  285. !BIO_indent(bp, indent, 128) ||
  286. BIO_puts(bp, "Mask Algorithm: ") <= 0) {
  287. goto err;
  288. }
  289. if (pss->maskGenAlgorithm) {
  290. if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 ||
  291. BIO_puts(bp, " with ") <= 0) {
  292. goto err;
  293. }
  294. if (maskHash) {
  295. if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) {
  296. goto err;
  297. }
  298. } else if (BIO_puts(bp, "INVALID") <= 0) {
  299. goto err;
  300. }
  301. } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) {
  302. goto err;
  303. }
  304. BIO_puts(bp, "\n");
  305. if (!BIO_indent(bp, indent, 128) ||
  306. BIO_puts(bp, "Salt Length: 0x") <= 0) {
  307. goto err;
  308. }
  309. if (pss->saltLength) {
  310. if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) {
  311. goto err;
  312. }
  313. } else if (BIO_puts(bp, "14 (default)") <= 0) {
  314. goto err;
  315. }
  316. BIO_puts(bp, "\n");
  317. if (!BIO_indent(bp, indent, 128) ||
  318. BIO_puts(bp, "Trailer Field: 0x") <= 0) {
  319. goto err;
  320. }
  321. if (pss->trailerField) {
  322. if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) {
  323. goto err;
  324. }
  325. } else if (BIO_puts(bp, "BC (default)") <= 0) {
  326. goto err;
  327. }
  328. BIO_puts(bp, "\n");
  329. rv = 1;
  330. err:
  331. RSA_PSS_PARAMS_free(pss);
  332. X509_ALGOR_free(maskHash);
  333. return rv;
  334. }