You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

269 lines
7.7 KiB

  1. /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  2. * 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/evp.h>
  56. #include <openssl/digest.h>
  57. #include <openssl/bn.h>
  58. #include <openssl/bytestring.h>
  59. #include <openssl/dsa.h>
  60. #include <openssl/err.h>
  61. #include "internal.h"
  62. static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
  63. // See RFC 3279, section 2.3.2.
  64. // Parameters may or may not be present.
  65. DSA *dsa;
  66. if (CBS_len(params) == 0) {
  67. dsa = DSA_new();
  68. if (dsa == NULL) {
  69. return 0;
  70. }
  71. } else {
  72. dsa = DSA_parse_parameters(params);
  73. if (dsa == NULL || CBS_len(params) != 0) {
  74. OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
  75. goto err;
  76. }
  77. }
  78. dsa->pub_key = BN_new();
  79. if (dsa->pub_key == NULL) {
  80. goto err;
  81. }
  82. if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
  83. CBS_len(key) != 0) {
  84. OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
  85. goto err;
  86. }
  87. EVP_PKEY_assign_DSA(out, dsa);
  88. return 1;
  89. err:
  90. DSA_free(dsa);
  91. return 0;
  92. }
  93. static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
  94. const DSA *dsa = key->pkey.dsa;
  95. const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
  96. // See RFC 5480, section 2.
  97. CBB spki, algorithm, oid, key_bitstring;
  98. if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
  99. !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
  100. !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
  101. !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
  102. (has_params &&
  103. !DSA_marshal_parameters(&algorithm, dsa)) ||
  104. !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
  105. !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
  106. !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
  107. !CBB_flush(out)) {
  108. OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
  109. return 0;
  110. }
  111. return 1;
  112. }
  113. static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
  114. // See PKCS#11, v2.40, section 2.5.
  115. // Decode parameters.
  116. BN_CTX *ctx = NULL;
  117. DSA *dsa = DSA_parse_parameters(params);
  118. if (dsa == NULL || CBS_len(params) != 0) {
  119. OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
  120. goto err;
  121. }
  122. dsa->priv_key = BN_new();
  123. dsa->pub_key = BN_new();
  124. if (dsa->priv_key == NULL || dsa->pub_key == NULL) {
  125. goto err;
  126. }
  127. // Decode the key.
  128. if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
  129. CBS_len(key) != 0) {
  130. OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
  131. goto err;
  132. }
  133. // Calculate the public key.
  134. ctx = BN_CTX_new();
  135. if (ctx == NULL ||
  136. !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
  137. ctx, NULL)) {
  138. goto err;
  139. }
  140. BN_CTX_free(ctx);
  141. EVP_PKEY_assign_DSA(out, dsa);
  142. return 1;
  143. err:
  144. BN_CTX_free(ctx);
  145. DSA_free(dsa);
  146. return 0;
  147. }
  148. static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
  149. const DSA *dsa = key->pkey.dsa;
  150. if (dsa == NULL || dsa->priv_key == NULL) {
  151. OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
  152. return 0;
  153. }
  154. // See PKCS#11, v2.40, section 2.5.
  155. CBB pkcs8, algorithm, oid, private_key;
  156. if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
  157. !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
  158. !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
  159. !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
  160. !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
  161. !DSA_marshal_parameters(&algorithm, dsa) ||
  162. !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
  163. !BN_marshal_asn1(&private_key, dsa->priv_key) ||
  164. !CBB_flush(out)) {
  165. OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
  166. return 0;
  167. }
  168. return 1;
  169. }
  170. static int int_dsa_size(const EVP_PKEY *pkey) {
  171. return DSA_size(pkey->pkey.dsa);
  172. }
  173. static int dsa_bits(const EVP_PKEY *pkey) {
  174. return BN_num_bits(pkey->pkey.dsa->p);
  175. }
  176. static int dsa_missing_parameters(const EVP_PKEY *pkey) {
  177. DSA *dsa;
  178. dsa = pkey->pkey.dsa;
  179. if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
  180. return 1;
  181. }
  182. return 0;
  183. }
  184. static int dup_bn_into(BIGNUM **out, BIGNUM *src) {
  185. BIGNUM *a;
  186. a = BN_dup(src);
  187. if (a == NULL) {
  188. return 0;
  189. }
  190. BN_free(*out);
  191. *out = a;
  192. return 1;
  193. }
  194. static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
  195. if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) ||
  196. !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) ||
  197. !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) {
  198. return 0;
  199. }
  200. return 1;
  201. }
  202. static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
  203. return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 &&
  204. BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 &&
  205. BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0;
  206. }
  207. static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
  208. return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0;
  209. }
  210. static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }
  211. const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
  212. EVP_PKEY_DSA,
  213. // 1.2.840.10040.4.1
  214. {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7,
  215. dsa_pub_decode,
  216. dsa_pub_encode,
  217. dsa_pub_cmp,
  218. dsa_priv_decode,
  219. dsa_priv_encode,
  220. NULL /* pkey_opaque */,
  221. int_dsa_size,
  222. dsa_bits,
  223. dsa_missing_parameters,
  224. dsa_copy_parameters,
  225. dsa_cmp_parameters,
  226. int_dsa_free,
  227. };