Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "gkm-rsa-mechanism.h"
24 : #include "gkm-sexp.h"
25 :
26 : #include "egg/egg-libgcrypt.h"
27 : #include "egg/egg-secure-memory.h"
28 :
29 : /* ----------------------------------------------------------------------------
30 : * PUBLIC
31 : */
32 :
33 : CK_RV
34 0 : gkm_rsa_mechanism_encrypt (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR data,
35 : CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
36 : {
37 : gcry_sexp_t splain, sdata;
38 : gcry_error_t gcry;
39 : guint nbits;
40 : CK_RV rv;
41 :
42 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
43 0 : g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
44 0 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
45 :
46 0 : nbits = gcry_pk_get_nbits (sexp);
47 0 : g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
48 :
49 : /* Just want to know the length */
50 0 : if (!encrypted) {
51 0 : *n_encrypted = (nbits + 7) / 8;
52 0 : return CKR_OK;
53 : }
54 :
55 : /* Prepare the input s expression */
56 0 : rv = gkm_crypto_data_to_sexp ("(data (flags raw) (value %m))",
57 : nbits, padding, data, n_data, &splain);
58 0 : if (rv != CKR_OK)
59 0 : return rv;
60 :
61 : /* Do the magic */
62 0 : gcry = gcry_pk_encrypt (&sdata, splain, sexp);
63 0 : gcry_sexp_release (splain);
64 :
65 : /* TODO: Certain codes should be returned (data too big etc... ) */
66 0 : if (gcry) {
67 0 : g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
68 0 : return CKR_FUNCTION_FAILED;
69 : }
70 :
71 : /* Now extract and send it back out */
72 0 : rv = gkm_crypto_sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL,
73 : "enc-val", "rsa", "a", NULL);
74 0 : gcry_sexp_release (sdata);
75 :
76 0 : return rv;
77 : }
78 :
79 : CK_RV
80 0 : gkm_rsa_mechanism_decrypt (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR encrypted,
81 : CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
82 : {
83 : gcry_sexp_t splain, sdata;
84 : gcry_error_t gcry;
85 : guint nbits;
86 : CK_RV rv;
87 :
88 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
89 0 : g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
90 0 : g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
91 :
92 0 : nbits = gcry_pk_get_nbits (sexp);
93 0 : g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
94 :
95 : /* Just want to know the length */
96 0 : if (!data) {
97 0 : *n_data = (nbits + 7) / 8;
98 0 : return CKR_OK;
99 : }
100 :
101 0 : if (n_encrypted != (nbits + 7) / 8)
102 0 : return CKR_DATA_LEN_RANGE;
103 :
104 : /* Prepare the input s expression */
105 0 : rv = gkm_crypto_data_to_sexp ("(enc-val (flags) (rsa (a %m)))",
106 : nbits, NULL, encrypted, n_encrypted, &sdata);
107 0 : if (rv != CKR_OK)
108 0 : return rv;
109 :
110 : /* Do the magic */
111 0 : gcry = gcry_pk_decrypt (&splain, sdata, sexp);
112 0 : gcry_sexp_release (sdata);
113 :
114 : /* TODO: Certain codes should be returned (data too big etc... ) */
115 0 : if (gcry) {
116 0 : g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
117 0 : return CKR_FUNCTION_FAILED;
118 : }
119 :
120 : /* Now extract and send it back out */
121 0 : rv = gkm_crypto_sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
122 0 : gcry_sexp_release (splain);
123 :
124 0 : return rv;
125 : }
126 :
127 : CK_RV
128 1 : gkm_rsa_mechanism_sign (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR data,
129 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
130 : {
131 : gcry_sexp_t ssig, sdata;
132 : guint nbits;
133 : gcry_error_t gcry;
134 : CK_RV rv;
135 :
136 1 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
137 1 : g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
138 1 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
139 :
140 1 : nbits = gcry_pk_get_nbits (sexp);
141 1 : g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
142 :
143 : /* Just want to know the length */
144 1 : if (!signature) {
145 0 : *n_signature = (nbits + 7) / 8;
146 0 : return CKR_OK;
147 : }
148 :
149 : /* Prepare the input sexp */
150 1 : rv = gkm_crypto_data_to_sexp ("(data (flags raw) (value %m))",
151 : nbits, padding, data, n_data, &sdata);
152 1 : if (rv != CKR_OK)
153 0 : return rv;
154 :
155 : /* Do the magic */
156 1 : gcry = gcry_pk_sign (&ssig, sdata, sexp);
157 1 : gcry_sexp_release (sdata);
158 :
159 : /* TODO: Certain codes should be returned (data too big etc... ) */
160 1 : if (gcry) {
161 0 : g_message ("signing of the data failed: %s", gcry_strerror (gcry));
162 0 : return CKR_FUNCTION_FAILED;
163 : }
164 :
165 : /* Now extract and send it back out */
166 1 : rv = gkm_crypto_sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
167 1 : gcry_sexp_release (ssig);
168 :
169 1 : return rv;
170 : }
171 :
172 : CK_RV
173 1 : gkm_rsa_mechanism_verify (gcry_sexp_t sexp, EggPadding padding, CK_BYTE_PTR data,
174 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
175 : {
176 : gcry_sexp_t ssig, sdata;
177 : gcry_error_t gcry;
178 : guint nbits;
179 : CK_RV rv;
180 :
181 1 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
182 1 : g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
183 1 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
184 :
185 : /* The key size */
186 1 : nbits = gcry_pk_get_nbits (sexp);
187 1 : g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
188 :
189 1 : if (n_signature != (nbits + 7) / 8)
190 0 : return CKR_SIGNATURE_LEN_RANGE;
191 :
192 : /* Prepare the input s expressions */
193 1 : rv = gkm_crypto_data_to_sexp ("(data (flags raw) (value %m))",
194 : nbits, padding, data, n_data, &sdata);
195 1 : if (rv != CKR_OK)
196 0 : return rv;
197 :
198 1 : rv = gkm_crypto_data_to_sexp ("(sig-val (rsa (s %m)))",
199 : nbits, NULL, signature, n_signature, &ssig);
200 1 : if (rv != CKR_OK) {
201 0 : gcry_sexp_release (sdata);
202 0 : return rv;
203 : }
204 :
205 : /* Do the magic */
206 1 : gcry = gcry_pk_verify (ssig, sdata, sexp);
207 1 : gcry_sexp_release (sdata);
208 1 : gcry_sexp_release (ssig);
209 :
210 : /* TODO: See if any other codes should be mapped */
211 1 : if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
212 0 : return CKR_SIGNATURE_INVALID;
213 1 : } else if (gcry) {
214 0 : g_message ("verifying of the data failed: %s", gcry_strerror (gcry));
215 0 : return CKR_FUNCTION_FAILED;
216 : }
217 :
218 1 : return CKR_OK;
219 : }
|