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 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include "dsa_locl.h" 13 #include <openssl/asn1.h> 14 #include <openssl/asn1t.h> 15 #include <openssl/rand.h> 16 17 ASN1_SEQUENCE(DSA_SIG) = { 18 ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), 19 ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) 20 } static_ASN1_SEQUENCE_END(DSA_SIG) 21 22 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) 23 24 DSA_SIG *DSA_SIG_new(void) 25 { 26 DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); 27 if (sig == NULL) 28 DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); 29 return sig; 30 } 31 32 void DSA_SIG_free(DSA_SIG *sig) 33 { 34 if (sig == NULL) 35 return; 36 BN_clear_free(sig->r); 37 BN_clear_free(sig->s); 38 OPENSSL_free(sig); 39 } 40 41 void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) 42 { 43 if (pr != NULL) 44 *pr = sig->r; 45 if (ps != NULL) 46 *ps = sig->s; 47 } 48 49 int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) 50 { 51 if (r == NULL || s == NULL) 52 return 0; 53 BN_clear_free(sig->r); 54 BN_clear_free(sig->s); 55 sig->r = r; 56 sig->s = s; 57 return 1; 58 } 59 60 /* Override the default free and new methods */ 61 static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 62 void *exarg) 63 { 64 if (operation == ASN1_OP_NEW_PRE) { 65 *pval = (ASN1_VALUE *)DSA_new(); 66 if (*pval != NULL) 67 return 2; 68 return 0; 69 } else if (operation == ASN1_OP_FREE_PRE) { 70 DSA_free((DSA *)*pval); 71 *pval = NULL; 72 return 2; 73 } 74 return 1; 75 } 76 77 ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { 78 ASN1_EMBED(DSA, version, INT32), 79 ASN1_SIMPLE(DSA, p, BIGNUM), 80 ASN1_SIMPLE(DSA, q, BIGNUM), 81 ASN1_SIMPLE(DSA, g, BIGNUM), 82 ASN1_SIMPLE(DSA, pub_key, BIGNUM), 83 ASN1_SIMPLE(DSA, priv_key, CBIGNUM) 84 } static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) 85 86 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) 87 88 ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { 89 ASN1_SIMPLE(DSA, p, BIGNUM), 90 ASN1_SIMPLE(DSA, q, BIGNUM), 91 ASN1_SIMPLE(DSA, g, BIGNUM), 92 } static_ASN1_SEQUENCE_END_cb(DSA, DSAparams) 93 94 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) 95 96 ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = { 97 ASN1_SIMPLE(DSA, pub_key, BIGNUM), 98 ASN1_SIMPLE(DSA, p, BIGNUM), 99 ASN1_SIMPLE(DSA, q, BIGNUM), 100 ASN1_SIMPLE(DSA, g, BIGNUM) 101 } static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey) 102 103 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) 104 105 DSA *DSAparams_dup(DSA *dsa) 106 { 107 return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); 108 } 109 110 int DSA_sign(int type, const unsigned char *dgst, int dlen, 111 unsigned char *sig, unsigned int *siglen, DSA *dsa) 112 { 113 DSA_SIG *s; 114 115 s = DSA_do_sign(dgst, dlen, dsa); 116 if (s == NULL) { 117 *siglen = 0; 118 return 0; 119 } 120 *siglen = i2d_DSA_SIG(s, &sig); 121 DSA_SIG_free(s); 122 return 1; 123 } 124 125 /* data has already been hashed (probably with SHA or SHA-1). */ 126 /*- 127 * returns 128 * 1: correct signature 129 * 0: incorrect signature 130 * -1: error 131 */ 132 int DSA_verify(int type, const unsigned char *dgst, int dgst_len, 133 const unsigned char *sigbuf, int siglen, DSA *dsa) 134 { 135 DSA_SIG *s; 136 const unsigned char *p = sigbuf; 137 unsigned char *der = NULL; 138 int derlen = -1; 139 int ret = -1; 140 141 s = DSA_SIG_new(); 142 if (s == NULL) 143 return ret; 144 if (d2i_DSA_SIG(&s, &p, siglen) == NULL) 145 goto err; 146 /* Ensure signature uses DER and doesn't have trailing garbage */ 147 derlen = i2d_DSA_SIG(s, &der); 148 if (derlen != siglen || memcmp(sigbuf, der, derlen)) 149 goto err; 150 ret = DSA_do_verify(dgst, dgst_len, s, dsa); 151 err: 152 OPENSSL_clear_free(der, derlen); 153 DSA_SIG_free(s); 154 return ret; 155 } 156