A local copy of OpenSSL from GitHub
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.

130 lines
3.5 KiB

  1. /*
  2. * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include "dsa_locl.h"
  12. #include <openssl/asn1.h>
  13. #include <openssl/asn1t.h>
  14. #include <openssl/rand.h>
  15. struct DSA_SIG_st {
  16. BIGNUM *r;
  17. BIGNUM *s;
  18. };
  19. ASN1_SEQUENCE(DSA_SIG) = {
  20. ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
  21. ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
  22. } static_ASN1_SEQUENCE_END(DSA_SIG)
  23. IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
  24. void DSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, const DSA_SIG *sig)
  25. {
  26. *pr = sig->r;
  27. *ps = sig->s;
  28. }
  29. /* Override the default free and new methods */
  30. static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
  31. void *exarg)
  32. {
  33. if (operation == ASN1_OP_NEW_PRE) {
  34. *pval = (ASN1_VALUE *)DSA_new();
  35. if (*pval != NULL)
  36. return 2;
  37. return 0;
  38. } else if (operation == ASN1_OP_FREE_PRE) {
  39. DSA_free((DSA *)*pval);
  40. *pval = NULL;
  41. return 2;
  42. }
  43. return 1;
  44. }
  45. ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
  46. ASN1_SIMPLE(DSA, version, LONG),
  47. ASN1_SIMPLE(DSA, p, BIGNUM),
  48. ASN1_SIMPLE(DSA, q, BIGNUM),
  49. ASN1_SIMPLE(DSA, g, BIGNUM),
  50. ASN1_SIMPLE(DSA, pub_key, BIGNUM),
  51. ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
  52. } static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
  53. IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
  54. ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
  55. ASN1_SIMPLE(DSA, p, BIGNUM),
  56. ASN1_SIMPLE(DSA, q, BIGNUM),
  57. ASN1_SIMPLE(DSA, g, BIGNUM),
  58. } static_ASN1_SEQUENCE_END_cb(DSA, DSAparams)
  59. IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
  60. ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
  61. ASN1_SIMPLE(DSA, pub_key, BIGNUM),
  62. ASN1_SIMPLE(DSA, p, BIGNUM),
  63. ASN1_SIMPLE(DSA, q, BIGNUM),
  64. ASN1_SIMPLE(DSA, g, BIGNUM)
  65. } static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey)
  66. IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
  67. DSA *DSAparams_dup(DSA *dsa)
  68. {
  69. return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
  70. }
  71. int DSA_sign(int type, const unsigned char *dgst, int dlen,
  72. unsigned char *sig, unsigned int *siglen, DSA *dsa)
  73. {
  74. DSA_SIG *s;
  75. RAND_seed(dgst, dlen);
  76. s = DSA_do_sign(dgst, dlen, dsa);
  77. if (s == NULL) {
  78. *siglen = 0;
  79. return (0);
  80. }
  81. *siglen = i2d_DSA_SIG(s, &sig);
  82. DSA_SIG_free(s);
  83. return (1);
  84. }
  85. /* data has already been hashed (probably with SHA or SHA-1). */
  86. /*-
  87. * returns
  88. * 1: correct signature
  89. * 0: incorrect signature
  90. * -1: error
  91. */
  92. int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
  93. const unsigned char *sigbuf, int siglen, DSA *dsa)
  94. {
  95. DSA_SIG *s;
  96. const unsigned char *p = sigbuf;
  97. unsigned char *der = NULL;
  98. int derlen = -1;
  99. int ret = -1;
  100. s = DSA_SIG_new();
  101. if (s == NULL)
  102. return (ret);
  103. if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
  104. goto err;
  105. /* Ensure signature uses DER and doesn't have trailing garbage */
  106. derlen = i2d_DSA_SIG(s, &der);
  107. if (derlen != siglen || memcmp(sigbuf, der, derlen))
  108. goto err;
  109. ret = DSA_do_verify(dgst, dgst_len, s, dsa);
  110. err:
  111. OPENSSL_clear_free(der, derlen);
  112. DSA_SIG_free(s);
  113. return (ret);
  114. }