]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
d2e9e320 | 2 | * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
9d6b1ce6 | 3 | * |
d2e9e320 RS |
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 | |
9d6b1ce6 | 8 | */ |
a8da8918 UM |
9 | |
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
b5acbf91 | 12 | #include "dsa_local.h" |
ec577822 | 13 | #include <openssl/asn1.h> |
9d6b1ce6 | 14 | #include <openssl/asn1t.h> |
f7a2afa6 | 15 | #include <openssl/rand.h> |
40f43f8a | 16 | |
706a13f1 | 17 | ASN1_SEQUENCE(DSA_SIG) = { |
0f113f3e MC |
18 | ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), |
19 | ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) | |
706a13f1 | 20 | } static_ASN1_SEQUENCE_END(DSA_SIG) |
9d6b1ce6 | 21 | |
8cc44d97 DSH |
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 | } | |
9d6b1ce6 | 40 | |
9267c11b | 41 | void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) |
706a13f1 | 42 | { |
9267c11b EK |
43 | if (pr != NULL) |
44 | *pr = sig->r; | |
45 | if (ps != NULL) | |
46 | *ps = sig->s; | |
706a13f1 DSH |
47 | } |
48 | ||
7ca3ea22 | 49 | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) |
6a571a18 | 50 | { |
bbaa9dd8 TS |
51 | if (r == NULL || s == NULL) |
52 | return 0; | |
6a571a18 TS |
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 | ||
9d6b1ce6 | 60 | /* Override the default free and new methods */ |
24484759 | 61 | static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
0f113f3e | 62 | void *exarg) |
a8da8918 | 63 | { |
0f113f3e MC |
64 | if (operation == ASN1_OP_NEW_PRE) { |
65 | *pval = (ASN1_VALUE *)DSA_new(); | |
90945fa3 | 66 | if (*pval != NULL) |
0f113f3e MC |
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; | |
a8da8918 UM |
75 | } |
76 | ||
9d6b1ce6 | 77 | ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { |
9612e157 | 78 | ASN1_EMBED(DSA, version, INT32), |
0f113f3e MC |
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), | |
74924dcb | 83 | ASN1_SIMPLE(DSA, priv_key, CBIGNUM) |
df2ee0e2 | 84 | } static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) |
a8da8918 | 85 | |
9d6b1ce6 | 86 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) |
a8da8918 | 87 | |
9d6b1ce6 | 88 | ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { |
0f113f3e MC |
89 | ASN1_SIMPLE(DSA, p, BIGNUM), |
90 | ASN1_SIMPLE(DSA, q, BIGNUM), | |
91 | ASN1_SIMPLE(DSA, g, BIGNUM), | |
df2ee0e2 | 92 | } static_ASN1_SEQUENCE_END_cb(DSA, DSAparams) |
a8da8918 | 93 | |
9d6b1ce6 | 94 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) |
a8da8918 | 95 | |
987157f6 | 96 | ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = { |
0f113f3e MC |
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) | |
987157f6 | 101 | } static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey) |
9d6b1ce6 DSH |
102 | |
103 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) | |
f4274da1 DSH |
104 | |
105 | DSA *DSAparams_dup(DSA *dsa) | |
0f113f3e MC |
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; | |
75e2c877 | 114 | |
0f113f3e MC |
115 | s = DSA_do_sign(dgst, dlen, dsa); |
116 | if (s == NULL) { | |
117 | *siglen = 0; | |
26a7d938 | 118 | return 0; |
0f113f3e MC |
119 | } |
120 | *siglen = i2d_DSA_SIG(s, &sig); | |
121 | DSA_SIG_free(s); | |
208fb891 | 122 | return 1; |
0f113f3e | 123 | } |
f7a2afa6 DSH |
124 | |
125 | /* data has already been hashed (probably with SHA or SHA-1). */ | |
1d97c843 TH |
126 | /*- |
127 | * returns | |
f7a2afa6 DSH |
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, | |
0f113f3e MC |
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) | |
26a7d938 | 143 | return ret; |
0f113f3e MC |
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: | |
4b45c6e5 | 152 | OPENSSL_clear_free(der, derlen); |
0f113f3e | 153 | DSA_SIG_free(s); |
26a7d938 | 154 | return ret; |
0f113f3e | 155 | } |