1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 2010-2020. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 
21 #include "dss.h"
22 #include "bn.h"
23 
24 #ifdef HAVE_DSA
25 
get_dss_private_key(ErlNifEnv * env,ERL_NIF_TERM key,DSA * dsa)26 int get_dss_private_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa)
27 {
28     /* key=[P,Q,G,KEY] */
29     ERL_NIF_TERM head, tail;
30     BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
31     BIGNUM *dummy_pub_key = NULL, *priv_key = NULL;
32 
33     if (!enif_get_list_cell(env, key, &head, &tail))
34         goto err;
35     if (!get_bn_from_bin(env, head, &dsa_p))
36         goto err;
37 
38     if (!enif_get_list_cell(env, tail, &head, &tail))
39         goto err;
40     if (!get_bn_from_bin(env, head, &dsa_q))
41         goto err;
42 
43     if (!enif_get_list_cell(env, tail, &head, &tail))
44         goto err;
45     if (!get_bn_from_bin(env, head, &dsa_g))
46         goto err;
47 
48     if (!enif_get_list_cell(env, tail, &head, &tail))
49         goto err;
50     if (!get_bn_from_bin(env, head, &priv_key))
51         goto err;
52 
53     if (!enif_is_empty_list(env, tail))
54         goto err;
55 
56     /* Note: DSA_set0_key() does not allow setting only the
57      * private key, although DSA_sign() does not use the
58      * public key. Work around this limitation by setting
59      * the public key to a copy of the private key.
60      */
61     if ((dummy_pub_key = BN_dup(priv_key)) == NULL)
62         goto err;
63 
64     if (!DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g))
65         goto err;
66     /* dsa takes ownership on success */
67     dsa_p = NULL;
68     dsa_q = NULL;
69     dsa_g = NULL;
70 
71     if (!DSA_set0_key(dsa, dummy_pub_key, priv_key))
72         goto err;
73     /* dsa takes ownership on success */
74     dummy_pub_key = NULL;
75     priv_key = NULL;
76 
77     return 1;
78 
79  err:
80     if (dsa_p)
81         BN_free(dsa_p);
82     if (dsa_q)
83         BN_free(dsa_q);
84     if (dsa_g)
85         BN_free(dsa_g);
86     if (priv_key)
87         BN_free(priv_key);
88     if (dummy_pub_key)
89         BN_free(dummy_pub_key);
90     return 0;
91 }
92 
get_dss_public_key(ErlNifEnv * env,ERL_NIF_TERM key,DSA * dsa)93 int get_dss_public_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa)
94 {
95     /* key=[P, Q, G, Y] */
96     ERL_NIF_TERM head, tail;
97     BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_y = NULL;
98 
99     if (!enif_get_list_cell(env, key, &head, &tail))
100         goto err;
101     if (!get_bn_from_bin(env, head, &dsa_p))
102         goto err;
103 
104     if (!enif_get_list_cell(env, tail, &head, &tail))
105         goto err;
106     if (!get_bn_from_bin(env, head, &dsa_q))
107         goto err;
108 
109     if (!enif_get_list_cell(env, tail, &head, &tail))
110         goto err;
111     if (!get_bn_from_bin(env, head, &dsa_g))
112         goto err;
113 
114     if (!enif_get_list_cell(env, tail, &head, &tail))
115         goto err;
116     if (!get_bn_from_bin(env, head, &dsa_y))
117         goto err;
118 
119     if (!enif_is_empty_list(env,tail))
120         goto err;
121 
122     if (!DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g))
123         goto err;
124     /* dsa takes ownership on success */
125     dsa_p = NULL;
126     dsa_q = NULL;
127     dsa_g = NULL;
128 
129     if (!DSA_set0_key(dsa, dsa_y, NULL))
130         goto err;
131     /* dsa takes ownership on success */
132     dsa_y = NULL;
133 
134     return 1;
135 
136  err:
137     if (dsa_p)
138         BN_free(dsa_p);
139     if (dsa_q)
140         BN_free(dsa_q);
141     if (dsa_g)
142         BN_free(dsa_g);
143     if (dsa_y)
144         BN_free(dsa_y);
145     return 0;
146 }
147 
148 #endif
149