~ubuntu-branches/ubuntu/natty/gnome-keyring/natty

« back to all changes in this revision

Viewing changes to pkcs11/gck/gck-sexp.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-02-16 19:00:06 UTC
  • mfrom: (1.1.58 upstream)
  • Revision ID: james.westby@ubuntu.com-20100216190006-cqpnic4zxlkmmi0o
Tags: 2.29.90git20100218-0ubuntu1
Updated to a git snapshot version

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
                                                     (GBoxedFreeFunc)gck_sexp_unref);
78
78
        return type;
79
79
}
 
80
 
 
81
#define PUBLIC_KEY "public-key"
 
82
#define PUBLIC_KEY_L 10
 
83
#define PRIVATE_KEY "private-key"
 
84
#define PRIVATE_KEY_L 11
 
85
 
 
86
gboolean
 
87
gck_sexp_parse_key (gcry_sexp_t s_key, int *algorithm, gboolean *is_private,
 
88
                    gcry_sexp_t *numbers)
 
89
{
 
90
        gboolean ret = FALSE;
 
91
        gcry_sexp_t child = NULL;
 
92
        gchar *str = NULL;
 
93
        const gchar *data;
 
94
        gsize n_data;
 
95
        gboolean priv;
 
96
        int algo;
 
97
 
 
98
        data = gcry_sexp_nth_data (s_key, 0, &n_data);
 
99
        if (!data)
 
100
                goto done;
 
101
 
 
102
        if (n_data == PUBLIC_KEY_L && strncmp (data, PUBLIC_KEY, PUBLIC_KEY_L) == 0)
 
103
                priv = FALSE;
 
104
        else if (n_data == PRIVATE_KEY_L && strncmp (data, PRIVATE_KEY, PRIVATE_KEY_L) == 0)
 
105
                priv = TRUE;
 
106
        else
 
107
                goto done;
 
108
 
 
109
        child = gcry_sexp_nth (s_key, 1);
 
110
        if (!child)
 
111
                goto done;
 
112
 
 
113
        data = gcry_sexp_nth_data (child, 0, &n_data);
 
114
        if (!data)
 
115
                goto done;
 
116
 
 
117
        str = g_alloca (n_data + 1);
 
118
        memcpy (str, data, n_data);
 
119
        str[n_data] = 0;
 
120
 
 
121
        algo = gcry_pk_map_name (str);
 
122
        if (!algo)
 
123
                goto done;
 
124
 
 
125
        /* Yay all done */
 
126
        if (algorithm)
 
127
                *algorithm = algo;
 
128
        if (numbers) {
 
129
                *numbers = child;
 
130
                child = NULL;
 
131
        }
 
132
        if (is_private)
 
133
                *is_private = priv;
 
134
 
 
135
        ret = TRUE;
 
136
 
 
137
done:
 
138
        gcry_sexp_release (child);
 
139
        return ret;
 
140
}
 
141
 
 
142
static gcry_sexp_t
 
143
rsa_numbers_to_public (gcry_sexp_t rsa)
 
144
{
 
145
        gcry_sexp_t pubkey = NULL;
 
146
        gcry_mpi_t n, e;
 
147
        gcry_error_t gcry;
 
148
 
 
149
        n = e = NULL;
 
150
 
 
151
        if (!gck_sexp_extract_mpi (rsa, &n, "n", NULL) ||
 
152
            !gck_sexp_extract_mpi (rsa, &e, "e", NULL))
 
153
                goto done;
 
154
 
 
155
        gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
 
156
                                n, e);
 
157
        if (gcry)
 
158
                goto done;
 
159
        g_assert (pubkey);
 
160
 
 
161
done:
 
162
        gcry_mpi_release (n);
 
163
        gcry_mpi_release (e);
 
164
 
 
165
        return pubkey;
 
166
}
 
167
 
 
168
static gcry_sexp_t
 
169
dsa_numbers_to_public (gcry_sexp_t dsa)
 
170
{
 
171
        gcry_mpi_t p, q, g, y;
 
172
        gcry_sexp_t pubkey = NULL;
 
173
        gcry_error_t gcry;
 
174
 
 
175
        p = q = g = y = NULL;
 
176
 
 
177
        if (!gck_sexp_extract_mpi (dsa, &p, "p", NULL) ||
 
178
            !gck_sexp_extract_mpi (dsa, &q, "q", NULL) ||
 
179
            !gck_sexp_extract_mpi (dsa, &g, "g", NULL) ||
 
180
            !gck_sexp_extract_mpi (dsa, &y, "y", NULL))
 
181
                goto done;
 
182
 
 
183
        gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
 
184
                                p, q, g, y);
 
185
        if (gcry)
 
186
                goto done;
 
187
        g_assert (pubkey);
 
188
 
 
189
done:
 
190
        gcry_mpi_release (p);
 
191
        gcry_mpi_release (q);
 
192
        gcry_mpi_release (g);
 
193
        gcry_mpi_release (y);
 
194
 
 
195
        return pubkey;
 
196
}
 
197
 
 
198
gboolean
 
199
gck_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
 
200
{
 
201
        gcry_sexp_t numbers;
 
202
        int algorithm;
 
203
 
 
204
        if (!gck_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
 
205
                g_return_val_if_reached (FALSE);
 
206
 
 
207
        switch (algorithm) {
 
208
        case GCRY_PK_RSA:
 
209
                *pubkey = rsa_numbers_to_public (numbers);
 
210
                break;
 
211
        case GCRY_PK_DSA:
 
212
                *pubkey = dsa_numbers_to_public (numbers);
 
213
                break;
 
214
        default:
 
215
                g_return_val_if_reached (FALSE);
 
216
        }
 
217
 
 
218
        gcry_sexp_release (numbers);
 
219
        return *pubkey ? TRUE : FALSE;
 
220
}
 
221
 
 
222
gboolean
 
223
gck_sexp_extract_mpi (gcry_sexp_t sexp, gcry_mpi_t *mpi, ...)
 
224
{
 
225
        gcry_sexp_t at = NULL;
 
226
        va_list va;
 
227
 
 
228
        g_assert (sexp);
 
229
        g_assert (mpi);
 
230
 
 
231
        va_start (va, mpi);
 
232
        at = gck_sexp_get_childv (sexp, va);
 
233
        va_end (va);
 
234
 
 
235
        *mpi = NULL;
 
236
        if (at)
 
237
                *mpi = gcry_sexp_nth_mpi (at ? at : sexp, 1, GCRYMPI_FMT_USG);
 
238
        if (at)
 
239
                gcry_sexp_release (at);
 
240
 
 
241
        return (*mpi) ? TRUE : FALSE;
 
242
}
 
243
 
 
244
gcry_sexp_t
 
245
gck_sexp_get_childv (gcry_sexp_t sexp, va_list va)
 
246
{
 
247
        gcry_sexp_t at = NULL;
 
248
        gcry_sexp_t child;
 
249
        const char *name;
 
250
 
 
251
        g_assert (sexp);
 
252
        g_assert (va);
 
253
 
 
254
        for(;;) {
 
255
                name = va_arg (va, const char*);
 
256
                if (!name)
 
257
                        break;
 
258
 
 
259
                child = gcry_sexp_find_token (at ? at : sexp, name, 0);
 
260
                gcry_sexp_release (at);
 
261
                at = child;
 
262
                if (at == NULL)
 
263
                        break;
 
264
        }
 
265
 
 
266
        va_end (va);
 
267
 
 
268
        return at;
 
269
}
 
270
 
 
271
void
 
272
gck_sexp_dump (gcry_sexp_t sexp)
 
273
{
 
274
        gsize len;
 
275
        gchar *buf;
 
276
 
 
277
        len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
 
278
        buf = g_malloc (len);
 
279
        gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, len);
 
280
        g_printerr ("%s", buf);
 
281
        g_free (buf);
 
282
}