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_local.h" 13#include <openssl/asn1.h> 14#include <openssl/asn1t.h> 15#include <openssl/rand.h> 16 17ASN1_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 22IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) 23 24DSA_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 32void 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 41void 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 49int 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 */ 61static 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 77ASN1_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 86IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) 87 88ASN1_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 94IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) 95 96ASN1_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 103IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) 104 105DSA *DSAparams_dup(DSA *dsa) 106{ 107 return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); 108} 109 110int 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 */ 132int 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