Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* gkr-pkix-asn1.c - ASN.1 helper routines
3 :
4 : Copyright (C) 2007 Stefan Walter
5 :
6 : The Gnome Keyring Library is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Library General Public License as
8 : published by the Free Software Foundation; either version 2 of the
9 : License, or (at your option) any later version.
10 :
11 : The Gnome Keyring Library is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Library General Public License for more details.
15 :
16 : You should have received a copy of the GNU Library General Public
17 : License along with the Gnome Library; see the file COPYING.LIB. If not,
18 : <http://www.gnu.org/licenses/>.
19 :
20 : Author: Stef Walter <stef@memberwebs.com>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include "gkm-data-asn1.h"
26 :
27 : #include "egg/egg-asn1x.h"
28 :
29 : static gboolean
30 542 : gkm_data_asn1_read_mpi_internal (GNode *asn, gcry_mpi_t *mpi, GBytes *(*asn1_get)(GNode *))
31 : {
32 : gcry_error_t gcry;
33 : GBytes *buf;
34 : gsize sz;
35 :
36 542 : g_return_val_if_fail (asn, FALSE);
37 542 : g_return_val_if_fail (mpi, FALSE);
38 :
39 542 : buf = asn1_get (asn);
40 542 : if (!buf)
41 0 : return FALSE;
42 :
43 : /* Automatically stores in secure memory if DER data is secure */
44 542 : sz = g_bytes_get_size (buf);
45 542 : gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, g_bytes_get_data (buf, NULL), sz, &sz);
46 542 : g_bytes_unref (buf);
47 542 : if (gcry != 0)
48 0 : return FALSE;
49 :
50 542 : return TRUE;
51 : }
52 :
53 : static gboolean
54 76 : gkm_data_asn1_write_mpi_internal (GNode *asn, gcry_mpi_t mpi, void (*asn1_set)(GNode *, GBytes *))
55 : {
56 : gcry_error_t gcry;
57 : GBytes *bytes;
58 : gsize len;
59 : guchar *buf;
60 :
61 76 : g_return_val_if_fail (asn, FALSE);
62 76 : g_return_val_if_fail (mpi, FALSE);
63 :
64 : /* Get the size */
65 76 : gcry = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &len, mpi);
66 76 : g_return_val_if_fail (gcry == 0, FALSE);
67 76 : g_return_val_if_fail (len > 0, FALSE);
68 :
69 76 : buf = gcry_calloc_secure (len, 1);
70 :
71 76 : gcry = gcry_mpi_print (GCRYMPI_FMT_STD, buf, len, &len, mpi);
72 76 : g_return_val_if_fail (gcry == 0, FALSE);
73 :
74 76 : bytes = g_bytes_new_with_free_func (buf, len, gcry_free, buf);
75 76 : asn1_set (asn, bytes);
76 76 : g_bytes_unref (bytes);
77 :
78 76 : return TRUE;
79 : }
80 :
81 : /* ECDSA private key (d) is OCTET STRING encoded MPI */
82 : gboolean
83 10 : gkm_data_asn1_read_string_mpi (GNode *asn, gcry_mpi_t *mpi)
84 : {
85 10 : return gkm_data_asn1_read_mpi_internal (asn, mpi, egg_asn1x_get_string_as_bytes);
86 : }
87 :
88 : gboolean
89 4 : gkm_data_asn1_write_string_mpi (GNode *asn, gcry_mpi_t mpi)
90 : {
91 4 : return gkm_data_asn1_write_mpi_internal (asn, mpi, egg_asn1x_set_string_as_bytes);
92 : }
93 :
94 : gboolean
95 532 : gkm_data_asn1_read_mpi (GNode *asn, gcry_mpi_t *mpi)
96 : {
97 532 : return gkm_data_asn1_read_mpi_internal (asn, mpi, egg_asn1x_get_integer_as_raw);
98 : }
99 :
100 : gboolean
101 72 : gkm_data_asn1_write_mpi (GNode *asn, gcry_mpi_t mpi)
102 : {
103 72 : return gkm_data_asn1_write_mpi_internal (asn, mpi, egg_asn1x_set_integer_as_raw);
104 : }
105 :
106 : /* ECDSA CKA_EC_POINT encodes q value as a OCTET STRING in PKCS#11 */
107 : gboolean
108 2 : gkm_data_asn1_read_string (GNode *asn, GBytes **data)
109 : {
110 : GBytes *buf;
111 :
112 2 : g_return_val_if_fail (asn, FALSE);
113 2 : g_return_val_if_fail (data, FALSE);
114 :
115 2 : buf = egg_asn1x_get_string_as_bytes (asn);
116 2 : if (!buf)
117 0 : return FALSE;
118 :
119 2 : *data = buf;
120 2 : return TRUE;
121 : }
122 :
123 : gboolean
124 2 : gkm_data_asn1_write_string (GNode *asn, GBytes *data)
125 : {
126 2 : g_return_val_if_fail (asn, FALSE);
127 2 : g_return_val_if_fail (data, FALSE);
128 :
129 2 : egg_asn1x_set_string_as_bytes (asn, data);
130 :
131 2 : return TRUE;
132 : }
133 :
134 : /* ECDSA public key (q) is encoded as a bit string in PEM files */
135 : gboolean
136 11 : gkm_data_asn1_read_bit_string (GNode *asn, GBytes **data, gsize *data_bits)
137 : {
138 : GBytes *buf;
139 : guint n_bits;
140 :
141 11 : g_return_val_if_fail (asn, FALSE);
142 11 : g_return_val_if_fail (data, FALSE);
143 :
144 11 : buf = egg_asn1x_get_bits_as_raw (asn, &n_bits);
145 11 : if (!buf)
146 0 : return FALSE;
147 :
148 11 : *data = buf;
149 11 : *data_bits = n_bits;
150 11 : return TRUE;
151 : }
152 :
153 : gboolean
154 5 : gkm_data_asn1_write_bit_string (GNode *asn, GBytes *data, gsize data_bits)
155 : {
156 5 : g_return_val_if_fail (asn, FALSE);
157 5 : g_return_val_if_fail (data, FALSE);
158 :
159 5 : egg_asn1x_set_bits_as_raw (asn, data, data_bits);
160 :
161 5 : return TRUE;
162 : }
163 :
164 : /* ECDSA differentiates curves based on the OID */
165 : gboolean
166 11 : gkm_data_asn1_read_oid (GNode *asn, GQuark *oid)
167 : {
168 : GQuark q;
169 :
170 11 : g_return_val_if_fail (asn, FALSE);
171 11 : g_return_val_if_fail (oid, FALSE);
172 :
173 11 : q = egg_asn1x_get_oid_as_quark (asn);
174 11 : if (!q)
175 0 : return FALSE;
176 :
177 11 : *oid = q;
178 11 : return TRUE;
179 : }
180 :
181 : gboolean
182 5 : gkm_data_asn1_write_oid (GNode *asn, GQuark oid)
183 : {
184 5 : g_return_val_if_fail (asn, FALSE);
185 5 : g_return_val_if_fail (oid, FALSE);
186 :
187 5 : return egg_asn1x_set_oid_as_quark (asn, oid);
188 : }
|