~ubuntu-branches/ubuntu/precise/libssh/precise

« back to all changes in this revision

Viewing changes to libssh/keys.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2011-06-15 15:48:07 UTC
  • mfrom: (1.1.10 upstream) (4.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20110615154807-3muklcqfftr1vtch
Tags: 0.5.0-2
* debian/patches/0002-Check-for-NULL-pointers-in-string-c.patch:
  Consolidate patch (Should fix previous REJECT)
* Support multiarch spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * keys.c - decoding a public key or signature and verifying them
3
 
 *
4
 
 * This file is part of the SSH Library
5
 
 *
6
 
 * Copyright (c) 2003-2005 by Aris Adamantiadis
7
 
 *
8
 
 * The SSH Library is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU Lesser General Public License as published by
10
 
 * the Free Software Foundation; either version 2.1 of the License, or (at your
11
 
 * option) any later version.
12
 
 *
13
 
 * The SSH Library is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16
 
 * License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public License
19
 
 * along with the SSH Library; see the file COPYING.  If not, write to
20
 
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
 
 * MA 02111-1307, USA.
22
 
 */
23
 
 
24
 
#include <stdlib.h>
25
 
#include <string.h>
26
 
#ifdef HAVE_LIBCRYPTO
27
 
#include <openssl/dsa.h>
28
 
#include <openssl/rsa.h>
29
 
#endif
30
 
#include "libssh/priv.h"
31
 
#include "libssh/ssh2.h"
32
 
#include "libssh/server.h"
33
 
#include "libssh/buffer.h"
34
 
#include "libssh/agent.h"
35
 
#include "libssh/session.h"
36
 
#include "libssh/keys.h"
37
 
#include "libssh/dh.h"
38
 
#include "libssh/messages.h"
39
 
#include "libssh/string.h"
40
 
 
41
 
/** \addtogroup ssh_auth
42
 
 * @{
43
 
 */
44
 
/* Public key decoding functions */
45
 
 
46
 
const char *ssh_type_to_char(int type) {
47
 
  switch (type) {
48
 
    case TYPE_DSS:
49
 
      return "ssh-dss";
50
 
    case TYPE_RSA:
51
 
      return "ssh-rsa";
52
 
    case TYPE_RSA1:
53
 
      return "ssh-rsa1";
54
 
    default:
55
 
      return NULL;
56
 
  }
57
 
}
58
 
 
59
 
int ssh_type_from_name(const char *name) {
60
 
  if (strcmp(name, "rsa1") == 0) {
61
 
    return TYPE_RSA1;
62
 
  } else if (strcmp(name, "rsa") == 0) {
63
 
    return TYPE_RSA;
64
 
  } else if (strcmp(name, "dsa") == 0) {
65
 
    return TYPE_DSS;
66
 
  } else if (strcmp(name, "ssh-rsa1") == 0) {
67
 
    return TYPE_RSA1;
68
 
  } else if (strcmp(name, "ssh-rsa") == 0) {
69
 
    return TYPE_RSA;
70
 
  } else if (strcmp(name, "ssh-dss") == 0) {
71
 
    return TYPE_DSS;
72
 
  }
73
 
 
74
 
  return -1;
75
 
}
76
 
 
77
 
ssh_public_key publickey_make_dss(ssh_session session, ssh_buffer buffer) {
78
 
  ssh_string p = NULL;
79
 
  ssh_string q = NULL;
80
 
  ssh_string g = NULL;
81
 
  ssh_string pubkey = NULL;
82
 
  ssh_public_key key = NULL;
83
 
 
84
 
  key = malloc(sizeof(struct ssh_public_key_struct));
85
 
  if (key == NULL) {
86
 
    buffer_free(buffer);
87
 
    return NULL;
88
 
  }
89
 
 
90
 
  key->type = TYPE_DSS;
91
 
  key->type_c = ssh_type_to_char(key->type);
92
 
 
93
 
  p = buffer_get_ssh_string(buffer);
94
 
  q = buffer_get_ssh_string(buffer);
95
 
  g = buffer_get_ssh_string(buffer);
96
 
  pubkey = buffer_get_ssh_string(buffer);
97
 
 
98
 
  buffer_free(buffer); /* we don't need it anymore */
99
 
 
100
 
  if (p == NULL || q == NULL || g == NULL || pubkey == NULL) {
101
 
    ssh_set_error(session, SSH_FATAL, "Invalid DSA public key");
102
 
    goto error;
103
 
  }
104
 
 
105
 
#ifdef HAVE_LIBGCRYPT
106
 
  gcry_sexp_build(&key->dsa_pub, NULL,
107
 
      "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
108
 
      string_len(p), string_data(p),
109
 
      string_len(q), string_data(q),
110
 
      string_len(g), string_data(g),
111
 
      string_len(pubkey), string_data(pubkey));
112
 
  if (key->dsa_pub == NULL) {
113
 
    goto error;
114
 
  }
115
 
#elif defined HAVE_LIBCRYPTO
116
 
 
117
 
  key->dsa_pub = DSA_new();
118
 
  if (key->dsa_pub == NULL) {
119
 
    goto error;
120
 
  }
121
 
  key->dsa_pub->p = make_string_bn(p);
122
 
  key->dsa_pub->q = make_string_bn(q);
123
 
  key->dsa_pub->g = make_string_bn(g);
124
 
  key->dsa_pub->pub_key = make_string_bn(pubkey);
125
 
  if (key->dsa_pub->p == NULL ||
126
 
      key->dsa_pub->q == NULL ||
127
 
      key->dsa_pub->g == NULL ||
128
 
      key->dsa_pub->pub_key == NULL) {
129
 
    goto error;
130
 
  }
131
 
#endif /* HAVE_LIBCRYPTO */
132
 
 
133
 
#ifdef DEBUG_CRYPTO
134
 
  ssh_print_hexa("p", string_data(p), string_len(p));
135
 
  ssh_print_hexa("q", string_data(q), string_len(q));
136
 
  ssh_print_hexa("g", string_data(g), string_len(g));
137
 
#endif
138
 
 
139
 
  string_burn(p);
140
 
  string_free(p);
141
 
  string_burn(q);
142
 
  string_free(q);
143
 
  string_burn(g);
144
 
  string_free(g);
145
 
  string_burn(pubkey);
146
 
  string_free(pubkey);
147
 
 
148
 
  return key;
149
 
error:
150
 
  string_burn(p);
151
 
  string_free(p);
152
 
  string_burn(q);
153
 
  string_free(q);
154
 
  string_burn(g);
155
 
  string_free(g);
156
 
  string_burn(pubkey);
157
 
  string_free(pubkey);
158
 
  publickey_free(key);
159
 
 
160
 
  return NULL;
161
 
}
162
 
 
163
 
ssh_public_key publickey_make_rsa(ssh_session session, ssh_buffer buffer,
164
 
    int type) {
165
 
  ssh_string e = NULL;
166
 
  ssh_string n = NULL;
167
 
  ssh_public_key key = NULL;
168
 
 
169
 
  key = malloc(sizeof(struct ssh_public_key_struct));
170
 
  if (key == NULL) {
171
 
    buffer_free(buffer);
172
 
    return NULL;
173
 
  }
174
 
 
175
 
  key->type = type;
176
 
  key->type_c = ssh_type_to_char(key->type);
177
 
 
178
 
  e = buffer_get_ssh_string(buffer);
179
 
  n = buffer_get_ssh_string(buffer);
180
 
 
181
 
  buffer_free(buffer); /* we don't need it anymore */
182
 
 
183
 
  if(e == NULL || n == NULL) {
184
 
    ssh_set_error(session, SSH_FATAL, "Invalid RSA public key");
185
 
    goto error;
186
 
  }
187
 
#ifdef HAVE_LIBGCRYPT
188
 
  gcry_sexp_build(&key->rsa_pub, NULL,
189
 
      "(public-key(rsa(n %b)(e %b)))",
190
 
      string_len(n), string_data(n),
191
 
      string_len(e),string_data(e));
192
 
  if (key->rsa_pub == NULL) {
193
 
    goto error;
194
 
  }
195
 
#elif HAVE_LIBCRYPTO
196
 
  key->rsa_pub = RSA_new();
197
 
  if (key->rsa_pub == NULL) {
198
 
    goto error;
199
 
  }
200
 
 
201
 
  key->rsa_pub->e = make_string_bn(e);
202
 
  key->rsa_pub->n = make_string_bn(n);
203
 
  if (key->rsa_pub->e == NULL ||
204
 
      key->rsa_pub->n == NULL) {
205
 
    goto error;
206
 
  }
207
 
#endif
208
 
 
209
 
#ifdef DEBUG_CRYPTO
210
 
  ssh_print_hexa("e", string_data(e), string_len(e));
211
 
  ssh_print_hexa("n", string_data(n), string_len(n));
212
 
#endif
213
 
 
214
 
  string_burn(e);
215
 
  string_free(e);
216
 
  string_burn(n);
217
 
  string_free(n);
218
 
 
219
 
  return key;
220
 
error:
221
 
  string_burn(e);
222
 
  string_free(e);
223
 
  string_burn(n);
224
 
  string_free(n);
225
 
  publickey_free(key);
226
 
 
227
 
  return NULL;
228
 
}
229
 
 
230
 
void publickey_free(ssh_public_key key) {
231
 
  if (key == NULL) {
232
 
    return;
233
 
  }
234
 
 
235
 
  switch(key->type) {
236
 
    case TYPE_DSS:
237
 
#ifdef HAVE_LIBGCRYPT
238
 
      gcry_sexp_release(key->dsa_pub);
239
 
#elif HAVE_LIBCRYPTO
240
 
      DSA_free(key->dsa_pub);
241
 
#endif
242
 
      break;
243
 
    case TYPE_RSA:
244
 
    case TYPE_RSA1:
245
 
#ifdef HAVE_LIBGCRYPT
246
 
      gcry_sexp_release(key->rsa_pub);
247
 
#elif defined HAVE_LIBCRYPTO
248
 
      RSA_free(key->rsa_pub);
249
 
#endif
250
 
      break;
251
 
    default:
252
 
      break;
253
 
  }
254
 
  SAFE_FREE(key);
255
 
}
256
 
 
257
 
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s) {
258
 
  ssh_buffer tmpbuf = NULL;
259
 
  ssh_string type_s = NULL;
260
 
  char *type_c = NULL;
261
 
  int type;
262
 
 
263
 
  tmpbuf = buffer_new();
264
 
  if (tmpbuf == NULL) {
265
 
    return NULL;
266
 
  }
267
 
 
268
 
  if (buffer_add_data(tmpbuf, string_data(pubkey_s), string_len(pubkey_s)) < 0) {
269
 
    goto error;
270
 
  }
271
 
 
272
 
  type_s = buffer_get_ssh_string(tmpbuf);
273
 
  if (type_s == NULL) {
274
 
    ssh_set_error(session,SSH_FATAL,"Invalid public key format");
275
 
    goto error;
276
 
  }
277
 
 
278
 
  type_c = string_to_char(type_s);
279
 
  string_free(type_s);
280
 
  if (type_c == NULL) {
281
 
    goto error;
282
 
  }
283
 
 
284
 
  type = ssh_type_from_name(type_c);
285
 
  SAFE_FREE(type_c);
286
 
 
287
 
  switch (type) {
288
 
    case TYPE_DSS:
289
 
      return publickey_make_dss(session, tmpbuf);
290
 
    case TYPE_RSA:
291
 
    case TYPE_RSA1:
292
 
      return publickey_make_rsa(session, tmpbuf, type);
293
 
  }
294
 
 
295
 
  ssh_set_error(session, SSH_FATAL, "Unknown public key protocol %s",
296
 
      ssh_type_to_char(type));
297
 
 
298
 
error:
299
 
  buffer_free(tmpbuf);
300
 
  return NULL;
301
 
}
302
 
 
303
 
/** \brief Makes a PUBLIC_KEY object out of a PRIVATE_KEY object
304
 
 * \param prv the Private key
305
 
 * \returns the public key
306
 
 * \see publickey_to_string()
307
 
 */
308
 
ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
309
 
  ssh_public_key key = NULL;
310
 
#ifdef HAVE_LIBGCRYPT
311
 
  gcry_sexp_t sexp;
312
 
  const char *tmp = NULL;
313
 
  size_t size;
314
 
  ssh_string p = NULL;
315
 
  ssh_string q = NULL;
316
 
  ssh_string g = NULL;
317
 
  ssh_string y = NULL;
318
 
  ssh_string e = NULL;
319
 
  ssh_string n = NULL;
320
 
#endif /* HAVE_LIBGCRYPT */
321
 
 
322
 
  key = malloc(sizeof(struct ssh_public_key_struct));
323
 
  if (key == NULL) {
324
 
    return NULL;
325
 
  }
326
 
 
327
 
  key->type = prv->type;
328
 
  switch(key->type) {
329
 
    case TYPE_DSS:
330
 
#ifdef HAVE_LIBGCRYPT
331
 
      sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0);
332
 
      if (sexp == NULL) {
333
 
        goto error;
334
 
      }
335
 
      tmp = gcry_sexp_nth_data(sexp, 1, &size);
336
 
      p = string_new(size);
337
 
      if (p == NULL) {
338
 
        goto error;
339
 
      }
340
 
      string_fill(p,(char *) tmp, size);
341
 
      gcry_sexp_release(sexp);
342
 
 
343
 
      sexp = gcry_sexp_find_token(prv->dsa_priv,"q",0);
344
 
      if (sexp == NULL) {
345
 
        goto error;
346
 
      }
347
 
      tmp = gcry_sexp_nth_data(sexp,1,&size);
348
 
      q = string_new(size);
349
 
      if (q == NULL) {
350
 
        goto error;
351
 
      }
352
 
      string_fill(q,(char *) tmp,size);
353
 
      gcry_sexp_release(sexp);
354
 
 
355
 
      sexp = gcry_sexp_find_token(prv->dsa_priv, "g", 0);
356
 
      if (sexp == NULL) {
357
 
        goto error;
358
 
      }
359
 
      tmp = gcry_sexp_nth_data(sexp,1,&size);
360
 
      g = string_new(size);
361
 
      if (g == NULL) {
362
 
        goto error;
363
 
      }
364
 
      string_fill(g,(char *) tmp,size);
365
 
      gcry_sexp_release(sexp);
366
 
 
367
 
      sexp = gcry_sexp_find_token(prv->dsa_priv,"y",0);
368
 
      if (sexp == NULL) {
369
 
        goto error;
370
 
      }
371
 
      tmp = gcry_sexp_nth_data(sexp,1,&size);
372
 
      y = string_new(size);
373
 
      if (y == NULL) {
374
 
        goto error;
375
 
      }
376
 
      string_fill(y,(char *) tmp,size);
377
 
      gcry_sexp_release(sexp);
378
 
 
379
 
      gcry_sexp_build(&key->dsa_pub, NULL,
380
 
          "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))",
381
 
          string_len(p), string_data(p),
382
 
          string_len(q), string_data(q),
383
 
          string_len(g), string_data(g),
384
 
          string_len(y), string_data(y));
385
 
 
386
 
      string_burn(p);
387
 
      string_free(p);
388
 
      string_burn(q);
389
 
      string_free(q);
390
 
      string_burn(g);
391
 
      string_free(g);
392
 
      string_burn(y);
393
 
      string_free(y);
394
 
#elif defined HAVE_LIBCRYPTO
395
 
      key->dsa_pub = DSA_new();
396
 
      if (key->dsa_pub == NULL) {
397
 
        goto error;
398
 
      }
399
 
      key->dsa_pub->p = BN_dup(prv->dsa_priv->p);
400
 
      key->dsa_pub->q = BN_dup(prv->dsa_priv->q);
401
 
      key->dsa_pub->g = BN_dup(prv->dsa_priv->g);
402
 
      key->dsa_pub->pub_key = BN_dup(prv->dsa_priv->pub_key);
403
 
      if (key->dsa_pub->p == NULL ||
404
 
          key->dsa_pub->q == NULL ||
405
 
          key->dsa_pub->g == NULL ||
406
 
          key->dsa_pub->pub_key == NULL) {
407
 
        goto error;
408
 
      }
409
 
#endif /* HAVE_LIBCRYPTO */
410
 
      break;
411
 
    case TYPE_RSA:
412
 
    case TYPE_RSA1:
413
 
#ifdef HAVE_LIBGCRYPT
414
 
      sexp = gcry_sexp_find_token(prv->rsa_priv, "n", 0);
415
 
      if (sexp == NULL) {
416
 
        goto error;
417
 
      }
418
 
      tmp = gcry_sexp_nth_data(sexp, 1, &size);
419
 
      n = string_new(size);
420
 
      if (n == NULL) {
421
 
        goto error;
422
 
      }
423
 
      string_fill(n, (char *) tmp, size);
424
 
      gcry_sexp_release(sexp);
425
 
 
426
 
      sexp = gcry_sexp_find_token(prv->rsa_priv, "e", 0);
427
 
      if (sexp == NULL) {
428
 
        goto error;
429
 
      }
430
 
      tmp = gcry_sexp_nth_data(sexp, 1, &size);
431
 
      e = string_new(size);
432
 
      if (e == NULL) {
433
 
        goto error;
434
 
      }
435
 
      string_fill(e, (char *) tmp, size);
436
 
      gcry_sexp_release(sexp);
437
 
 
438
 
      gcry_sexp_build(&key->rsa_pub, NULL,
439
 
          "(public-key(rsa(n %b)(e %b)))",
440
 
          string_len(n), string_data(n),
441
 
          string_len(e), string_data(e));
442
 
      if (key->rsa_pub == NULL) {
443
 
        goto error;
444
 
      }
445
 
 
446
 
      string_burn(e);
447
 
      string_free(e);
448
 
      string_burn(n);
449
 
      string_free(n);
450
 
#elif defined HAVE_LIBCRYPTO
451
 
      key->rsa_pub = RSA_new();
452
 
      if (key->rsa_pub == NULL) {
453
 
        goto error;
454
 
      }
455
 
      key->rsa_pub->e = BN_dup(prv->rsa_priv->e);
456
 
      key->rsa_pub->n = BN_dup(prv->rsa_priv->n);
457
 
      if (key->rsa_pub->e == NULL ||
458
 
          key->rsa_pub->n == NULL) {
459
 
        goto error;
460
 
      }
461
 
#endif
462
 
      break;
463
 
  }
464
 
  key->type_c = ssh_type_to_char(prv->type);
465
 
 
466
 
  return key;
467
 
error:
468
 
#ifdef HAVE_LIBGCRYPT
469
 
  gcry_sexp_release(sexp);
470
 
  string_burn(p);
471
 
  string_free(p);
472
 
  string_burn(q);
473
 
  string_free(q);
474
 
  string_burn(g);
475
 
  string_free(g);
476
 
  string_burn(y);
477
 
  string_free(y);
478
 
 
479
 
  string_burn(e);
480
 
  string_free(e);
481
 
  string_burn(n);
482
 
  string_free(n);
483
 
#endif
484
 
  publickey_free(key);
485
 
 
486
 
  return NULL;
487
 
}
488
 
 
489
 
#ifdef HAVE_LIBGCRYPT
490
 
static int dsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
491
 
#elif defined HAVE_LIBCRYPTO
492
 
static int dsa_public_to_string(DSA *key, ssh_buffer buffer) {
493
 
#endif
494
 
  ssh_string p = NULL;
495
 
  ssh_string q = NULL;
496
 
  ssh_string g = NULL;
497
 
  ssh_string n = NULL;
498
 
 
499
 
  int rc = -1;
500
 
 
501
 
#ifdef HAVE_LIBGCRYPT
502
 
  const char *tmp = NULL;
503
 
  size_t size;
504
 
  gcry_sexp_t sexp;
505
 
 
506
 
  sexp = gcry_sexp_find_token(key, "p", 0);
507
 
  if (sexp == NULL) {
508
 
    goto error;
509
 
  }
510
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
511
 
  p = string_new(size);
512
 
  if (p == NULL) {
513
 
    goto error;
514
 
  }
515
 
  string_fill(p, (char *) tmp, size);
516
 
  gcry_sexp_release(sexp);
517
 
 
518
 
  sexp = gcry_sexp_find_token(key, "q", 0);
519
 
  if (sexp == NULL) {
520
 
    goto error;
521
 
  }
522
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
523
 
  q = string_new(size);
524
 
  if (q == NULL) {
525
 
    goto error;
526
 
  }
527
 
  string_fill(q, (char *) tmp, size);
528
 
  gcry_sexp_release(sexp);
529
 
 
530
 
  sexp = gcry_sexp_find_token(key, "g", 0);
531
 
  if (sexp == NULL) {
532
 
    goto error;
533
 
  }
534
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
535
 
  g = string_new(size);
536
 
  if (g == NULL) {
537
 
    goto error;
538
 
  }
539
 
  string_fill(g, (char *) tmp, size);
540
 
  gcry_sexp_release(sexp);
541
 
 
542
 
  sexp = gcry_sexp_find_token(key, "y", 0);
543
 
  if (sexp == NULL) {
544
 
    goto error;
545
 
  }
546
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
547
 
  n = string_new(size);
548
 
  if (n == NULL) {
549
 
    goto error;
550
 
  }
551
 
  string_fill(n, (char *) tmp, size);
552
 
 
553
 
#elif defined HAVE_LIBCRYPTO
554
 
  p = make_bignum_string(key->p);
555
 
  q = make_bignum_string(key->q);
556
 
  g = make_bignum_string(key->g);
557
 
  n = make_bignum_string(key->pub_key);
558
 
  if (p == NULL || q == NULL || g == NULL || n == NULL) {
559
 
    goto error;
560
 
  }
561
 
#endif /* HAVE_LIBCRYPTO */
562
 
  if (buffer_add_ssh_string(buffer, p) < 0) {
563
 
    goto error;
564
 
  }
565
 
  if (buffer_add_ssh_string(buffer, q) < 0) {
566
 
    goto error;
567
 
  }
568
 
  if (buffer_add_ssh_string(buffer, g) < 0) {
569
 
    goto error;
570
 
  }
571
 
  if (buffer_add_ssh_string(buffer, n) < 0) {
572
 
    goto error;
573
 
  }
574
 
 
575
 
  rc = 0;
576
 
error:
577
 
#ifdef HAVE_LIBGCRYPT
578
 
  gcry_sexp_release(sexp);
579
 
#endif
580
 
 
581
 
  string_burn(p);
582
 
  string_free(p);
583
 
  string_burn(q);
584
 
  string_free(q);
585
 
  string_burn(g);
586
 
  string_free(g);
587
 
  string_burn(n);
588
 
  string_free(n);
589
 
 
590
 
  return rc;
591
 
}
592
 
 
593
 
#ifdef HAVE_LIBGCRYPT
594
 
static int rsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) {
595
 
#elif defined HAVE_LIBCRYPTO
596
 
static int rsa_public_to_string(RSA *key, ssh_buffer buffer) {
597
 
#endif
598
 
 
599
 
  ssh_string e = NULL;
600
 
  ssh_string n = NULL;
601
 
 
602
 
  int rc = -1;
603
 
 
604
 
#ifdef HAVE_LIBGCRYPT
605
 
  const char *tmp;
606
 
  size_t size;
607
 
  gcry_sexp_t sexp;
608
 
 
609
 
  sexp = gcry_sexp_find_token(key, "n", 0);
610
 
  if (sexp == NULL) {
611
 
    goto error;
612
 
  }
613
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
614
 
  n = string_new(size);
615
 
  if (n == NULL) {
616
 
    goto error;
617
 
  }
618
 
  string_fill(n, (char *) tmp, size);
619
 
  gcry_sexp_release(sexp);
620
 
 
621
 
  sexp = gcry_sexp_find_token(key, "e", 0);
622
 
  if (sexp == NULL) {
623
 
    goto error;
624
 
  }
625
 
  tmp = gcry_sexp_nth_data(sexp, 1, &size);
626
 
  e = string_new(size);
627
 
  if (e == NULL) {
628
 
    goto error;
629
 
  }
630
 
  string_fill(e, (char *) tmp, size);
631
 
 
632
 
#elif defined HAVE_LIBCRYPTO
633
 
  e = make_bignum_string(key->e);
634
 
  n = make_bignum_string(key->n);
635
 
  if (e == NULL || n == NULL) {
636
 
    goto error;
637
 
  }
638
 
#endif
639
 
 
640
 
  if (buffer_add_ssh_string(buffer, e) < 0) {
641
 
    goto error;
642
 
  }
643
 
  if (buffer_add_ssh_string(buffer, n) < 0) {
644
 
    goto error;
645
 
  }
646
 
 
647
 
  rc = 0;
648
 
error:
649
 
#ifdef HAVE_LIBGCRYPT
650
 
  gcry_sexp_release(sexp);
651
 
#endif
652
 
 
653
 
  string_burn(e);
654
 
  string_free(e);
655
 
  string_burn(n);
656
 
  string_free(n);
657
 
 
658
 
  return rc;
659
 
}
660
 
 
661
 
/** \brief makes a SSH String out of a PUBLIC_KEY object
662
 
 * \param key the public key
663
 
 * \returns a SSH String containing the public key
664
 
 * \see string_free()
665
 
 */
666
 
ssh_string publickey_to_string(ssh_public_key key) {
667
 
  ssh_string type = NULL;
668
 
  ssh_string ret = NULL;
669
 
  ssh_buffer buf = NULL;
670
 
 
671
 
  buf = buffer_new();
672
 
  if (buf == NULL) {
673
 
    return NULL;
674
 
  }
675
 
 
676
 
  type = string_from_char(key->type_c);
677
 
  if (type == NULL) {
678
 
    goto error;
679
 
  }
680
 
 
681
 
  if (buffer_add_ssh_string(buf, type) < 0) {
682
 
    goto error;
683
 
  }
684
 
 
685
 
  switch (key->type) {
686
 
    case TYPE_DSS:
687
 
      if (dsa_public_to_string(key->dsa_pub, buf) < 0) {
688
 
        goto error;
689
 
      }
690
 
      break;
691
 
    case TYPE_RSA:
692
 
    case TYPE_RSA1:
693
 
      if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
694
 
        goto error;
695
 
      }
696
 
      break;
697
 
  }
698
 
 
699
 
  ret = string_new(buffer_get_len(buf));
700
 
  if (ret == NULL) {
701
 
    goto error;
702
 
  }
703
 
 
704
 
  string_fill(ret, buffer_get(buf), buffer_get_len(buf));
705
 
error:
706
 
  buffer_free(buf);
707
 
  string_free(type);
708
 
 
709
 
  return ret;
710
 
}
711
 
 
712
 
/* Signature decoding functions */
713
 
static ssh_string signature_to_string(SIGNATURE *sign) {
714
 
  unsigned char buffer[40] = {0};
715
 
  ssh_buffer tmpbuf = NULL;
716
 
  ssh_string str = NULL;
717
 
  ssh_string tmp = NULL;
718
 
  ssh_string rs = NULL;
719
 
  int rc = -1;
720
 
#ifdef HAVE_LIBGCRYPT
721
 
  const char *r = NULL;
722
 
  const char *s = NULL;
723
 
  gcry_sexp_t sexp;
724
 
  size_t size = 0;
725
 
#elif defined HAVE_LIBCRYPTO
726
 
  ssh_string r = NULL;
727
 
  ssh_string s = NULL;
728
 
#endif
729
 
 
730
 
  tmpbuf = buffer_new();
731
 
  if (tmpbuf == NULL) {
732
 
    return NULL;
733
 
  }
734
 
 
735
 
  tmp = string_from_char(ssh_type_to_char(sign->type));
736
 
  if (tmp == NULL) {
737
 
    buffer_free(tmpbuf);
738
 
    return NULL;
739
 
  }
740
 
  if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
741
 
    buffer_free(tmpbuf);
742
 
    string_free(tmp);
743
 
    return NULL;
744
 
  }
745
 
  string_free(tmp);
746
 
 
747
 
  switch(sign->type) {
748
 
    case TYPE_DSS:
749
 
#ifdef HAVE_LIBGCRYPT
750
 
      sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
751
 
      if (sexp == NULL) {
752
 
        buffer_free(tmpbuf);
753
 
        return NULL;
754
 
      }
755
 
      r = gcry_sexp_nth_data(sexp, 1, &size);
756
 
      if (*r == 0) {      /* libgcrypt put 0 when first bit is set */
757
 
        size--;
758
 
        r++;
759
 
      }
760
 
      memcpy(buffer, r + size - 20, 20);
761
 
      gcry_sexp_release(sexp);
762
 
 
763
 
      sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0);
764
 
      if (sexp == NULL) {
765
 
        buffer_free(tmpbuf);
766
 
        return NULL;
767
 
      }
768
 
      s = gcry_sexp_nth_data(sexp,1,&size);
769
 
      if (*s == 0) {
770
 
        size--;
771
 
        s++;
772
 
      }
773
 
      memcpy(buffer+ 20, s + size - 20, 20);
774
 
      gcry_sexp_release(sexp);
775
 
#elif defined HAVE_LIBCRYPTO
776
 
      r = make_bignum_string(sign->dsa_sign->r);
777
 
      if (r == NULL) {
778
 
        buffer_free(tmpbuf);
779
 
        return NULL;
780
 
      }
781
 
      s = make_bignum_string(sign->dsa_sign->s);
782
 
      if (s == NULL) {
783
 
        buffer_free(tmpbuf);
784
 
        string_free(r);
785
 
        return NULL;
786
 
      }
787
 
 
788
 
      memcpy(buffer, (char *)string_data(r) + string_len(r) - 20, 20);
789
 
      memcpy(buffer + 20, (char *)string_data(s) + string_len(s) - 20, 20);
790
 
 
791
 
      string_free(r);
792
 
      string_free(s);
793
 
#endif /* HAVE_LIBCRYPTO */
794
 
      rs = string_new(40);
795
 
      if (rs == NULL) {
796
 
        buffer_free(tmpbuf);
797
 
        return NULL;
798
 
      }
799
 
 
800
 
      string_fill(rs, buffer, 40);
801
 
      rc = buffer_add_ssh_string(tmpbuf, rs);
802
 
      string_free(rs);
803
 
      if (rc < 0) {
804
 
        buffer_free(tmpbuf);
805
 
        return NULL;
806
 
      }
807
 
 
808
 
      break;
809
 
    case TYPE_RSA:
810
 
    case TYPE_RSA1:
811
 
#ifdef HAVE_LIBGCRYPT
812
 
      sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0);
813
 
      if (sexp == NULL) {
814
 
        buffer_free(tmpbuf);
815
 
        return NULL;
816
 
      }
817
 
      s = gcry_sexp_nth_data(sexp,1,&size);
818
 
      if (*s == 0) {
819
 
        size--;
820
 
        s++;
821
 
      }
822
 
      rs = string_new(size);
823
 
      if (rs == NULL) {
824
 
        buffer_free(tmpbuf);
825
 
        return NULL;
826
 
      }
827
 
 
828
 
      string_fill(rs, (char *) s, size);
829
 
      rc = buffer_add_ssh_string(tmpbuf, rs);
830
 
      gcry_sexp_release(sexp);
831
 
      string_free(rs);
832
 
      if (rc < 0) {
833
 
        buffer_free(tmpbuf);
834
 
        return NULL;
835
 
      }
836
 
#elif defined HAVE_LIBCRYPTO
837
 
      if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) {
838
 
        buffer_free(tmpbuf);
839
 
        return NULL;
840
 
      }
841
 
#endif
842
 
      break;
843
 
  }
844
 
 
845
 
  str = string_new(buffer_get_len(tmpbuf));
846
 
  if (str == NULL) {
847
 
    buffer_free(tmpbuf);
848
 
    return NULL;
849
 
  }
850
 
  string_fill(str, buffer_get(tmpbuf), buffer_get_len(tmpbuf));
851
 
  buffer_free(tmpbuf);
852
 
 
853
 
  return str;
854
 
}
855
 
 
856
 
/* TODO : split this function in two so it becomes smaller */
857
 
SIGNATURE *signature_from_string(ssh_session session, ssh_string signature,
858
 
    ssh_public_key pubkey, int needed_type) {
859
 
  SIGNATURE *sign = NULL;
860
 
  ssh_buffer tmpbuf = NULL;
861
 
  ssh_string rs = NULL;
862
 
  ssh_string type_s = NULL;
863
 
  ssh_string e = NULL;
864
 
  char *type_c = NULL;
865
 
  int type;
866
 
  int len;
867
 
  int rsalen;
868
 
#ifdef HAVE_LIBGCRYPT
869
 
  gcry_sexp_t sig;
870
 
#elif defined HAVE_LIBCRYPTO
871
 
  DSA_SIG *sig = NULL;
872
 
  ssh_string r = NULL;
873
 
  ssh_string s = NULL;
874
 
#endif
875
 
 
876
 
  sign = malloc(sizeof(SIGNATURE));
877
 
  if (sign == NULL) {
878
 
    ssh_set_error(session, SSH_FATAL, "Not enough space");
879
 
    return NULL;
880
 
  }
881
 
 
882
 
  tmpbuf = buffer_new();
883
 
  if (tmpbuf == NULL) {
884
 
    ssh_set_error(session, SSH_FATAL, "Not enough space");
885
 
    signature_free(sign);
886
 
    return NULL;
887
 
  }
888
 
 
889
 
  if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature)) < 0) {
890
 
    signature_free(sign);
891
 
    buffer_free(tmpbuf);
892
 
    return NULL;
893
 
  }
894
 
 
895
 
  type_s = buffer_get_ssh_string(tmpbuf);
896
 
  if (type_s == NULL) {
897
 
    ssh_set_error(session, SSH_FATAL, "Invalid signature packet");
898
 
    signature_free(sign);
899
 
    buffer_free(tmpbuf);
900
 
    return NULL;
901
 
  }
902
 
 
903
 
  type_c = string_to_char(type_s);
904
 
  string_free(type_s);
905
 
  if (type_c == NULL) {
906
 
    signature_free(sign);
907
 
    buffer_free(tmpbuf);
908
 
    return NULL;
909
 
  }
910
 
  type = ssh_type_from_name(type_c);
911
 
  SAFE_FREE(type_c);
912
 
 
913
 
  if (needed_type != type) {
914
 
    ssh_set_error(session, SSH_FATAL, "Invalid signature type: %s",
915
 
        ssh_type_to_char(type));
916
 
    signature_free(sign);
917
 
    buffer_free(tmpbuf);
918
 
    return NULL;
919
 
  }
920
 
 
921
 
  switch(needed_type) {
922
 
    case TYPE_DSS:
923
 
      rs = buffer_get_ssh_string(tmpbuf);
924
 
      buffer_free(tmpbuf);
925
 
 
926
 
      /* 40 is the dual signature blob len. */
927
 
      if (rs == NULL || string_len(rs) != 40) {
928
 
        string_free(rs);
929
 
        signature_free(sign);
930
 
        return NULL;
931
 
      }
932
 
 
933
 
      /* we make use of strings (because we have all-made functions to convert
934
 
       * them to bignums (ou pas ;) */
935
 
#ifdef HAVE_LIBGCRYPT
936
 
      if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
937
 
            20 ,string_data(rs), 20,(unsigned char *)string_data(rs) + 20)) {
938
 
        string_free(rs);
939
 
        signature_free(sign);
940
 
        return NULL;
941
 
      }
942
 
#elif defined HAVE_LIBCRYPTO
943
 
      r = string_new(20);
944
 
      s = string_new(20);
945
 
      if (r == NULL || s == NULL) {
946
 
        string_free(r);
947
 
        string_free(s);
948
 
        string_free(rs);
949
 
        signature_free(sign);
950
 
        return NULL;
951
 
      }
952
 
 
953
 
      string_fill(r, string_data(rs), 20);
954
 
      string_fill(s, (char *)string_data(rs) + 20, 20);
955
 
 
956
 
      sig = DSA_SIG_new();
957
 
      if (sig == NULL) {
958
 
        string_free(r);
959
 
        string_free(s);
960
 
        string_free(rs);
961
 
        signature_free(sign);
962
 
        return NULL;
963
 
      }
964
 
      sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
965
 
      sig->s = make_string_bn(s);
966
 
      string_free(r);
967
 
      string_free(s);
968
 
 
969
 
      if (sig->r == NULL || sig->s == NULL) {
970
 
        string_free(rs);
971
 
        DSA_SIG_free(sig);
972
 
        signature_free(sign);
973
 
        return NULL;
974
 
      }
975
 
#endif
976
 
 
977
 
#ifdef DEBUG_CRYPTO
978
 
      ssh_print_hexa("r", string_data(rs), 20);
979
 
      ssh_print_hexa("s", (const unsigned char *)string_data(rs) + 20, 20);
980
 
#endif
981
 
      string_free(rs);
982
 
 
983
 
      sign->type = TYPE_DSS;
984
 
      sign->dsa_sign = sig;
985
 
 
986
 
      return sign;
987
 
    case TYPE_RSA:
988
 
      e = buffer_get_ssh_string(tmpbuf);
989
 
      buffer_free(tmpbuf);
990
 
      if (e == NULL) {
991
 
        signature_free(sign);
992
 
        return NULL;
993
 
      }
994
 
      len = string_len(e);
995
 
#ifdef HAVE_LIBGCRYPT
996
 
      rsalen = (gcry_pk_get_nbits(pubkey->rsa_pub) + 7) / 8;
997
 
#elif defined HAVE_LIBCRYPTO
998
 
      rsalen = RSA_size(pubkey->rsa_pub);
999
 
#endif
1000
 
      if (len > rsalen) {
1001
 
        string_free(e);
1002
 
        signature_free(sign);
1003
 
        ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d",
1004
 
            len, rsalen);
1005
 
        return NULL;
1006
 
      }
1007
 
 
1008
 
      if (len < rsalen) {
1009
 
        ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d",
1010
 
            len, rsalen);
1011
 
      }
1012
 
      sign->type = TYPE_RSA;
1013
 
#ifdef HAVE_LIBGCRYPT
1014
 
      if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
1015
 
          string_len(e), string_data(e))) {
1016
 
        signature_free(sign);
1017
 
        string_free(e);
1018
 
        return NULL;
1019
 
      }
1020
 
 
1021
 
      sign->rsa_sign = sig;
1022
 
#elif defined HAVE_LIBCRYPTO
1023
 
      sign->rsa_sign = e;
1024
 
#endif
1025
 
 
1026
 
#ifdef DEBUG_CRYPTO
1027
 
      ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len);
1028
 
      ssh_print_hexa("RSA signature", string_data(e), len);
1029
 
#endif
1030
 
 
1031
 
#ifdef HAVE_LIBGCRYPT
1032
 
      string_free(e);
1033
 
#endif
1034
 
 
1035
 
      return sign;
1036
 
    default:
1037
 
      return NULL;
1038
 
  }
1039
 
 
1040
 
  return NULL;
1041
 
}
1042
 
 
1043
 
void signature_free(SIGNATURE *sign) {
1044
 
  if (sign == NULL) {
1045
 
    return;
1046
 
  }
1047
 
 
1048
 
  switch(sign->type) {
1049
 
    case TYPE_DSS:
1050
 
#ifdef HAVE_LIBGCRYPT
1051
 
      gcry_sexp_release(sign->dsa_sign);
1052
 
#elif defined HAVE_LIBCRYPTO
1053
 
      DSA_SIG_free(sign->dsa_sign);
1054
 
#endif
1055
 
      break;
1056
 
    case TYPE_RSA:
1057
 
    case TYPE_RSA1:
1058
 
#ifdef HAVE_LIBGCRYPT
1059
 
      gcry_sexp_release(sign->rsa_sign);
1060
 
#elif defined HAVE_LIBCRYPTO
1061
 
      SAFE_FREE(sign->rsa_sign);
1062
 
#endif
1063
 
      break;
1064
 
    default:
1065
 
      /* FIXME Passing NULL segfaults */
1066
 
#if 0
1067
 
       ssh_log(NULL, SSH_LOG_RARE, "Freeing a signature with no type!\n"); */
1068
 
#endif
1069
 
         break;
1070
 
    }
1071
 
  SAFE_FREE(sign);
1072
 
}
1073
 
 
1074
 
#ifdef HAVE_LIBCRYPTO
1075
 
/*
1076
 
 * Maybe the missing function from libcrypto
1077
 
 *
1078
 
 * I think now, maybe it's a bad idea to name it has it should have be
1079
 
 * named in libcrypto
1080
 
 */
1081
 
static ssh_string RSA_do_sign(const unsigned char *payload, int len, RSA *privkey) {
1082
 
  ssh_string sign = NULL;
1083
 
  unsigned char *buffer = NULL;
1084
 
  unsigned int size;
1085
 
 
1086
 
  buffer = malloc(RSA_size(privkey));
1087
 
  if (buffer == NULL) {
1088
 
    return NULL;
1089
 
  }
1090
 
 
1091
 
  if (RSA_sign(NID_sha1, payload, len, buffer, &size, privkey) == 0) {
1092
 
    SAFE_FREE(buffer);
1093
 
    return NULL;
1094
 
  }
1095
 
 
1096
 
  sign = string_new(size);
1097
 
  if (sign == NULL) {
1098
 
    SAFE_FREE(buffer);
1099
 
    return NULL;
1100
 
  }
1101
 
 
1102
 
  string_fill(sign, buffer, size);
1103
 
  SAFE_FREE(buffer);
1104
 
 
1105
 
  return sign;
1106
 
}
1107
 
#endif
1108
 
 
1109
 
#ifndef _WIN32
1110
 
ssh_string ssh_do_sign_with_agent(ssh_session session,
1111
 
    struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) {
1112
 
  struct ssh_buffer_struct *sigbuf = NULL;
1113
 
  struct ssh_string_struct *signature = NULL;
1114
 
  struct ssh_string_struct *session_id = NULL;
1115
 
  struct ssh_crypto_struct *crypto = NULL;
1116
 
 
1117
 
  if (session->current_crypto) {
1118
 
    crypto = session->current_crypto;
1119
 
  } else {
1120
 
    crypto = session->next_crypto;
1121
 
  }
1122
 
 
1123
 
  /* prepend session identifier */
1124
 
  session_id = string_new(SHA_DIGEST_LEN);
1125
 
  if (session_id == NULL) {
1126
 
    return NULL;
1127
 
  }
1128
 
  string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);
1129
 
 
1130
 
  sigbuf = buffer_new();
1131
 
  if (sigbuf == NULL) {
1132
 
    string_free(session_id);
1133
 
    return NULL;
1134
 
  }
1135
 
 
1136
 
  if (buffer_add_ssh_string(sigbuf, session_id) < 0) {
1137
 
    buffer_free(sigbuf);
1138
 
    string_free(session_id);
1139
 
    return NULL;
1140
 
  }
1141
 
  string_free(session_id);
1142
 
 
1143
 
  /* append out buffer */
1144
 
  if (buffer_add_buffer(sigbuf, buf) < 0) {
1145
 
    buffer_free(sigbuf);
1146
 
    return NULL;
1147
 
  }
1148
 
 
1149
 
  /* create signature */
1150
 
  signature = agent_sign_data(session, sigbuf, publickey);
1151
 
 
1152
 
  buffer_free(sigbuf);
1153
 
 
1154
 
  return signature;
1155
 
}
1156
 
#endif /* _WIN32 */
1157
 
 
1158
 
/*
1159
 
 * This function concats in a buffer the values needed to do a signature
1160
 
 * verification. */
1161
 
ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service) {
1162
 
/*
1163
 
     The value of 'signature' is a signature by the corresponding private
1164
 
   key over the following data, in the following order:
1165
 
 
1166
 
      string    session identifier
1167
 
      byte      SSH_MSG_USERAUTH_REQUEST
1168
 
      string    user name
1169
 
      string    service name
1170
 
      string    "publickey"
1171
 
      boolean   TRUE
1172
 
      string    public key algorithm name
1173
 
      string    public key to be used for authentication
1174
 
*/
1175
 
        struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto :
1176
 
                                             session->next_crypto;
1177
 
  ssh_buffer buffer = NULL;
1178
 
  ssh_string session_id = NULL;
1179
 
  uint8_t type = SSH2_MSG_USERAUTH_REQUEST;
1180
 
  ssh_string username = string_from_char(msg->auth_request.username);
1181
 
  ssh_string servicename = string_from_char(service);
1182
 
  ssh_string method = string_from_char("publickey");
1183
 
  uint8_t has_sign = 1;
1184
 
  ssh_string algo = string_from_char(msg->auth_request.public_key->type_c);
1185
 
  ssh_string publickey = publickey_to_string(msg->auth_request.public_key);
1186
 
 
1187
 
  buffer = buffer_new();
1188
 
  if (buffer == NULL) {
1189
 
    goto error;
1190
 
  }
1191
 
  session_id = string_new(SHA_DIGEST_LEN);
1192
 
  if (session_id == NULL) {
1193
 
    buffer_free(buffer);
1194
 
    buffer = NULL;
1195
 
    goto error;
1196
 
  }
1197
 
  string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);
1198
 
 
1199
 
  if(buffer_add_ssh_string(buffer, session_id) < 0 ||
1200
 
     buffer_add_u8(buffer, type) < 0 ||
1201
 
     buffer_add_ssh_string(buffer, username) < 0 ||
1202
 
     buffer_add_ssh_string(buffer, servicename) < 0 ||
1203
 
     buffer_add_ssh_string(buffer, method) < 0 ||
1204
 
     buffer_add_u8(buffer, has_sign) < 0 ||
1205
 
     buffer_add_ssh_string(buffer, algo) < 0 ||
1206
 
     buffer_add_ssh_string(buffer, publickey) < 0) {
1207
 
    buffer_free(buffer);
1208
 
    buffer = NULL;
1209
 
    goto error;
1210
 
  }
1211
 
 
1212
 
error:
1213
 
  if(session_id) string_free(session_id);
1214
 
  if(username) string_free(username);
1215
 
  if(servicename) string_free(servicename);
1216
 
  if(method) string_free(method);
1217
 
  if(algo) string_free(algo);
1218
 
  if(publickey) string_free(publickey);
1219
 
  return buffer;
1220
 
}
1221
 
 
1222
 
/*
1223
 
 * This function signs the session id (known as H) as a string then
1224
 
 * the content of sigbuf */
1225
 
ssh_string ssh_do_sign(ssh_session session, ssh_buffer sigbuf,
1226
 
    ssh_private_key privatekey) {
1227
 
  struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto :
1228
 
    session->next_crypto;
1229
 
  unsigned char hash[SHA_DIGEST_LEN + 1] = {0};
1230
 
  ssh_string session_str = NULL;
1231
 
  ssh_string signature = NULL;
1232
 
  SIGNATURE *sign = NULL;
1233
 
  SHACTX ctx = NULL;
1234
 
#ifdef HAVE_LIBGCRYPT
1235
 
  gcry_sexp_t gcryhash;
1236
 
#endif
1237
 
 
1238
 
  session_str = string_new(SHA_DIGEST_LEN);
1239
 
  if (session_str == NULL) {
1240
 
    return NULL;
1241
 
  }
1242
 
  string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN);
1243
 
 
1244
 
  ctx = sha1_init();
1245
 
  if (ctx == NULL) {
1246
 
    string_free(session_str);
1247
 
    return NULL;
1248
 
  }
1249
 
 
1250
 
  sha1_update(ctx, session_str, string_len(session_str) + 4);
1251
 
  string_free(session_str);
1252
 
  sha1_update(ctx, buffer_get(sigbuf), buffer_get_len(sigbuf));
1253
 
  sha1_final(hash + 1,ctx);
1254
 
  hash[0] = 0;
1255
 
 
1256
 
#ifdef DEBUG_CRYPTO
1257
 
  ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN);
1258
 
#endif
1259
 
 
1260
 
  sign = malloc(sizeof(SIGNATURE));
1261
 
  if (sign == NULL) {
1262
 
    return NULL;
1263
 
  }
1264
 
 
1265
 
  switch(privatekey->type) {
1266
 
    case TYPE_DSS:
1267
 
#ifdef HAVE_LIBGCRYPT
1268
 
      if (gcry_sexp_build(&gcryhash, NULL, "%b", SHA_DIGEST_LEN + 1, hash) ||
1269
 
          gcry_pk_sign(&sign->dsa_sign, gcryhash, privatekey->dsa_priv)) {
1270
 
        ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error");
1271
 
        gcry_sexp_release(gcryhash);
1272
 
        signature_free(sign);
1273
 
        return NULL;
1274
 
      }
1275
 
#elif defined HAVE_LIBCRYPTO
1276
 
      sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN,
1277
 
          privatekey->dsa_priv);
1278
 
      if (sign->dsa_sign == NULL) {
1279
 
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
1280
 
        signature_free(sign);
1281
 
        return NULL;
1282
 
      }
1283
 
#ifdef DEBUG_CRYPTO
1284
 
      ssh_print_bignum("r", sign->dsa_sign->r);
1285
 
      ssh_print_bignum("s", sign->dsa_sign->s);
1286
 
#endif
1287
 
#endif /* HAVE_LIBCRYPTO */
1288
 
      sign->rsa_sign = NULL;
1289
 
      break;
1290
 
    case TYPE_RSA:
1291
 
#ifdef HAVE_LIBGCRYPT
1292
 
      if (gcry_sexp_build(&gcryhash, NULL, "(data(flags pkcs1)(hash sha1 %b))",
1293
 
            SHA_DIGEST_LEN, hash + 1) ||
1294
 
          gcry_pk_sign(&sign->rsa_sign, gcryhash, privatekey->rsa_priv)) {
1295
 
        ssh_set_error(session, SSH_FATAL, "Signing: libcrypt error");
1296
 
        gcry_sexp_release(gcryhash);
1297
 
        signature_free(sign);
1298
 
        return NULL;
1299
 
      }
1300
 
#elif defined HAVE_LIBCRYPTO
1301
 
      sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN,
1302
 
          privatekey->rsa_priv);
1303
 
      if (sign->rsa_sign == NULL) {
1304
 
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
1305
 
        signature_free(sign);
1306
 
        return NULL;
1307
 
      }
1308
 
#endif
1309
 
      sign->dsa_sign = NULL;
1310
 
      break;
1311
 
    default:
1312
 
      signature_free(sign);
1313
 
      return NULL;
1314
 
  }
1315
 
#ifdef HAVE_LIBGCRYPT
1316
 
  gcry_sexp_release(gcryhash);
1317
 
#endif
1318
 
 
1319
 
  sign->type = privatekey->type;
1320
 
 
1321
 
  signature = signature_to_string(sign);
1322
 
  signature_free(sign);
1323
 
 
1324
 
  return signature;
1325
 
}
1326
 
 
1327
 
ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_public_key key) {
1328
 
  ssh_string str = NULL;
1329
 
  size_t len = string_len(data);
1330
 
  size_t size = 0;
1331
 
#ifdef HAVE_LIBGCRYPT
1332
 
  const char *tmp = NULL;
1333
 
  gcry_sexp_t ret_sexp;
1334
 
  gcry_sexp_t data_sexp;
1335
 
 
1336
 
  if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))",
1337
 
      len, string_data(data))) {
1338
 
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
1339
 
    return NULL;
1340
 
  }
1341
 
  if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) {
1342
 
    gcry_sexp_release(data_sexp);
1343
 
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
1344
 
    return NULL;
1345
 
  }
1346
 
 
1347
 
  gcry_sexp_release(data_sexp);
1348
 
 
1349
 
  data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0);
1350
 
  if (data_sexp == NULL) {
1351
 
    ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
1352
 
    gcry_sexp_release(ret_sexp);
1353
 
    return NULL;
1354
 
  }
1355
 
  tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
1356
 
  if (*tmp == 0) {
1357
 
    size--;
1358
 
    tmp++;
1359
 
  }
1360
 
 
1361
 
  str = string_new(size);
1362
 
  if (str == NULL) {
1363
 
    ssh_set_error(session, SSH_FATAL, "Not enough space");
1364
 
    gcry_sexp_release(data_sexp);
1365
 
    gcry_sexp_release(ret_sexp);
1366
 
    return NULL;
1367
 
  }
1368
 
  string_fill(str, tmp, size);
1369
 
 
1370
 
  gcry_sexp_release(data_sexp);
1371
 
  gcry_sexp_release(ret_sexp);
1372
 
#elif defined HAVE_LIBCRYPTO
1373
 
  size = RSA_size(key->rsa_pub);
1374
 
 
1375
 
  str = string_new(size);
1376
 
  if (str == NULL) {
1377
 
    ssh_set_error(session, SSH_FATAL, "Not enough space");
1378
 
    return NULL;
1379
 
  }
1380
 
 
1381
 
  if (RSA_public_encrypt(len, string_data(data), string_data(str), key->rsa_pub,
1382
 
      RSA_PKCS1_PADDING) < 0) {
1383
 
    string_free(str);
1384
 
    return NULL;
1385
 
  }
1386
 
#endif
1387
 
 
1388
 
  return str;
1389
 
}
1390
 
 
1391
 
 
1392
 
/* this function signs the session id */
1393
 
ssh_string ssh_sign_session_id(ssh_session session, ssh_private_key privatekey) {
1394
 
        struct ssh_crypto_struct *crypto=session->current_crypto ? session->current_crypto :
1395
 
    session->next_crypto;
1396
 
  unsigned char hash[SHA_DIGEST_LEN + 1] = {0};
1397
 
  ssh_string signature = NULL;
1398
 
  SIGNATURE *sign = NULL;
1399
 
  SHACTX ctx = NULL;
1400
 
#ifdef HAVE_LIBGCRYPT
1401
 
  gcry_sexp_t data_sexp;
1402
 
#endif
1403
 
 
1404
 
  ctx = sha1_init();
1405
 
  if (ctx == NULL) {
1406
 
    return NULL;
1407
 
  }
1408
 
  sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN);
1409
 
  sha1_final(hash + 1,ctx);
1410
 
  hash[0] = 0;
1411
 
 
1412
 
#ifdef DEBUG_CRYPTO
1413
 
  ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN);
1414
 
#endif
1415
 
 
1416
 
  sign = malloc(sizeof(SIGNATURE));
1417
 
  if (sign == NULL) {
1418
 
    return NULL;
1419
 
  }
1420
 
 
1421
 
  switch(privatekey->type) {
1422
 
    case TYPE_DSS:
1423
 
#ifdef HAVE_LIBGCRYPT
1424
 
      if (gcry_sexp_build(&data_sexp, NULL, "%b", SHA_DIGEST_LEN + 1, hash) ||
1425
 
          gcry_pk_sign(&sign->dsa_sign, data_sexp, privatekey->dsa_priv)) {
1426
 
        ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error");
1427
 
        gcry_sexp_release(data_sexp);
1428
 
        signature_free(sign);
1429
 
        return NULL;
1430
 
      }
1431
 
#elif defined HAVE_LIBCRYPTO
1432
 
      sign->dsa_sign = DSA_do_sign(hash + 1, SHA_DIGEST_LEN,
1433
 
          privatekey->dsa_priv);
1434
 
      if (sign->dsa_sign == NULL) {
1435
 
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
1436
 
        signature_free(sign);
1437
 
        return NULL;
1438
 
      }
1439
 
 
1440
 
#ifdef DEBUG_CRYPTO
1441
 
      ssh_print_bignum("r",sign->dsa_sign->r);
1442
 
      ssh_print_bignum("s",sign->dsa_sign->s);
1443
 
#endif
1444
 
 
1445
 
#endif /* HAVE_LIBCRYPTO */
1446
 
      sign->rsa_sign = NULL;
1447
 
      break;
1448
 
    case TYPE_RSA:
1449
 
#ifdef HAVE_LIBGCRYPT
1450
 
      if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))",
1451
 
            SHA_DIGEST_LEN, hash + 1) ||
1452
 
          gcry_pk_sign(&sign->rsa_sign, data_sexp, privatekey->rsa_priv)) {
1453
 
        ssh_set_error(session, SSH_FATAL, "Signing: libgcrypt error");
1454
 
        gcry_sexp_release(data_sexp);
1455
 
        signature_free(sign);
1456
 
        return NULL;
1457
 
      }
1458
 
#elif defined HAVE_LIBCRYPTO
1459
 
      sign->rsa_sign = RSA_do_sign(hash + 1, SHA_DIGEST_LEN,
1460
 
          privatekey->rsa_priv);
1461
 
      if (sign->rsa_sign == NULL) {
1462
 
        ssh_set_error(session, SSH_FATAL, "Signing: openssl error");
1463
 
        signature_free(sign);
1464
 
        return NULL;
1465
 
      }
1466
 
#endif
1467
 
      sign->dsa_sign = NULL;
1468
 
      break;
1469
 
    default:
1470
 
      signature_free(sign);
1471
 
      return NULL;
1472
 
  }
1473
 
 
1474
 
#ifdef HAVE_LIBGCRYPT
1475
 
  gcry_sexp_release(data_sexp);
1476
 
#endif
1477
 
 
1478
 
  sign->type = privatekey->type;
1479
 
 
1480
 
  signature = signature_to_string(sign);
1481
 
  signature_free(sign);
1482
 
 
1483
 
  return signature;
1484
 
}
1485
 
 
1486
 
/** @} */
1487
 
/* vim: set ts=2 sw=2 et cindent: */