/src/openssl/crypto/dsa/dsa_asn1.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
26 | 0 | DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); |
27 | 0 | if (sig == NULL) |
28 | 0 | DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); |
29 | 0 | return sig; |
30 | 0 | } |
31 | | |
32 | | void DSA_SIG_free(DSA_SIG *sig) |
33 | 0 | { |
34 | 0 | if (sig == NULL) |
35 | 0 | return; |
36 | 0 | BN_clear_free(sig->r); |
37 | 0 | BN_clear_free(sig->s); |
38 | 0 | OPENSSL_free(sig); |
39 | 0 | } |
40 | | |
41 | | void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) |
42 | 0 | { |
43 | 0 | if (pr != NULL) |
44 | 0 | *pr = sig->r; |
45 | 0 | if (ps != NULL) |
46 | 0 | *ps = sig->s; |
47 | 0 | } |
48 | | |
49 | | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) |
50 | 0 | { |
51 | 0 | if (r == NULL || s == NULL) |
52 | 0 | return 0; |
53 | 0 | BN_clear_free(sig->r); |
54 | 0 | BN_clear_free(sig->s); |
55 | 0 | sig->r = r; |
56 | 0 | sig->s = s; |
57 | 0 | return 1; |
58 | 0 | } |
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 | 0 | { |
64 | 0 | if (operation == ASN1_OP_NEW_PRE) { |
65 | 0 | *pval = (ASN1_VALUE *)DSA_new(); |
66 | 0 | if (*pval != NULL) |
67 | 0 | return 2; |
68 | 0 | return 0; |
69 | 0 | } else if (operation == ASN1_OP_FREE_PRE) { |
70 | 0 | DSA_free((DSA *)*pval); |
71 | 0 | *pval = NULL; |
72 | 0 | return 2; |
73 | 0 | } |
74 | 0 | return 1; |
75 | 0 | } |
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 | 0 | { |
107 | 0 | return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); |
108 | 0 | } |
109 | | |
110 | | int DSA_sign(int type, const unsigned char *dgst, int dlen, |
111 | | unsigned char *sig, unsigned int *siglen, DSA *dsa) |
112 | 0 | { |
113 | 0 | DSA_SIG *s; |
114 | 0 |
|
115 | 0 | s = DSA_do_sign(dgst, dlen, dsa); |
116 | 0 | if (s == NULL) { |
117 | 0 | *siglen = 0; |
118 | 0 | return 0; |
119 | 0 | } |
120 | 0 | *siglen = i2d_DSA_SIG(s, &sig); |
121 | 0 | DSA_SIG_free(s); |
122 | 0 | return 1; |
123 | 0 | } |
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 | 0 | { |
135 | 0 | DSA_SIG *s; |
136 | 0 | const unsigned char *p = sigbuf; |
137 | 0 | unsigned char *der = NULL; |
138 | 0 | int derlen = -1; |
139 | 0 | int ret = -1; |
140 | 0 |
|
141 | 0 | s = DSA_SIG_new(); |
142 | 0 | if (s == NULL) |
143 | 0 | return ret; |
144 | 0 | if (d2i_DSA_SIG(&s, &p, siglen) == NULL) |
145 | 0 | goto err; |
146 | 0 | /* Ensure signature uses DER and doesn't have trailing garbage */ |
147 | 0 | derlen = i2d_DSA_SIG(s, &der); |
148 | 0 | if (derlen != siglen || memcmp(sigbuf, der, derlen)) |
149 | 0 | goto err; |
150 | 0 | ret = DSA_do_verify(dgst, dgst_len, s, dsa); |
151 | 0 | err: |
152 | 0 | OPENSSL_clear_free(der, derlen); |
153 | 0 | DSA_SIG_free(s); |
154 | 0 | return ret; |
155 | 0 | } |