2
* keys.c - decoding a public key or signature and verifying them
4
* This file is part of the SSH Library
6
* Copyright (c) 2003-2005 by Aris Adamantiadis
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.
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.
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,
27
#include <openssl/dsa.h>
28
#include <openssl/rsa.h>
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"
41
/** \addtogroup ssh_auth
44
/* Public key decoding functions */
46
const char *ssh_type_to_char(int type) {
59
int ssh_type_from_name(const char *name) {
60
if (strcmp(name, "rsa1") == 0) {
62
} else if (strcmp(name, "rsa") == 0) {
64
} else if (strcmp(name, "dsa") == 0) {
66
} else if (strcmp(name, "ssh-rsa1") == 0) {
68
} else if (strcmp(name, "ssh-rsa") == 0) {
70
} else if (strcmp(name, "ssh-dss") == 0) {
77
ssh_public_key publickey_make_dss(ssh_session session, ssh_buffer buffer) {
81
ssh_string pubkey = NULL;
82
ssh_public_key key = NULL;
84
key = malloc(sizeof(struct ssh_public_key_struct));
91
key->type_c = ssh_type_to_char(key->type);
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);
98
buffer_free(buffer); /* we don't need it anymore */
100
if (p == NULL || q == NULL || g == NULL || pubkey == NULL) {
101
ssh_set_error(session, SSH_FATAL, "Invalid DSA public key");
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) {
115
#elif defined HAVE_LIBCRYPTO
117
key->dsa_pub = DSA_new();
118
if (key->dsa_pub == NULL) {
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) {
131
#endif /* HAVE_LIBCRYPTO */
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));
163
ssh_public_key publickey_make_rsa(ssh_session session, ssh_buffer buffer,
167
ssh_public_key key = NULL;
169
key = malloc(sizeof(struct ssh_public_key_struct));
176
key->type_c = ssh_type_to_char(key->type);
178
e = buffer_get_ssh_string(buffer);
179
n = buffer_get_ssh_string(buffer);
181
buffer_free(buffer); /* we don't need it anymore */
183
if(e == NULL || n == NULL) {
184
ssh_set_error(session, SSH_FATAL, "Invalid RSA public key");
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) {
196
key->rsa_pub = RSA_new();
197
if (key->rsa_pub == NULL) {
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) {
210
ssh_print_hexa("e", string_data(e), string_len(e));
211
ssh_print_hexa("n", string_data(n), string_len(n));
230
void publickey_free(ssh_public_key key) {
237
#ifdef HAVE_LIBGCRYPT
238
gcry_sexp_release(key->dsa_pub);
240
DSA_free(key->dsa_pub);
245
#ifdef HAVE_LIBGCRYPT
246
gcry_sexp_release(key->rsa_pub);
247
#elif defined HAVE_LIBCRYPTO
248
RSA_free(key->rsa_pub);
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;
263
tmpbuf = buffer_new();
264
if (tmpbuf == NULL) {
268
if (buffer_add_data(tmpbuf, string_data(pubkey_s), string_len(pubkey_s)) < 0) {
272
type_s = buffer_get_ssh_string(tmpbuf);
273
if (type_s == NULL) {
274
ssh_set_error(session,SSH_FATAL,"Invalid public key format");
278
type_c = string_to_char(type_s);
280
if (type_c == NULL) {
284
type = ssh_type_from_name(type_c);
289
return publickey_make_dss(session, tmpbuf);
292
return publickey_make_rsa(session, tmpbuf, type);
295
ssh_set_error(session, SSH_FATAL, "Unknown public key protocol %s",
296
ssh_type_to_char(type));
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()
308
ssh_public_key publickey_from_privatekey(ssh_private_key prv) {
309
ssh_public_key key = NULL;
310
#ifdef HAVE_LIBGCRYPT
312
const char *tmp = NULL;
320
#endif /* HAVE_LIBGCRYPT */
322
key = malloc(sizeof(struct ssh_public_key_struct));
327
key->type = prv->type;
330
#ifdef HAVE_LIBGCRYPT
331
sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0);
335
tmp = gcry_sexp_nth_data(sexp, 1, &size);
336
p = string_new(size);
340
string_fill(p,(char *) tmp, size);
341
gcry_sexp_release(sexp);
343
sexp = gcry_sexp_find_token(prv->dsa_priv,"q",0);
347
tmp = gcry_sexp_nth_data(sexp,1,&size);
348
q = string_new(size);
352
string_fill(q,(char *) tmp,size);
353
gcry_sexp_release(sexp);
355
sexp = gcry_sexp_find_token(prv->dsa_priv, "g", 0);
359
tmp = gcry_sexp_nth_data(sexp,1,&size);
360
g = string_new(size);
364
string_fill(g,(char *) tmp,size);
365
gcry_sexp_release(sexp);
367
sexp = gcry_sexp_find_token(prv->dsa_priv,"y",0);
371
tmp = gcry_sexp_nth_data(sexp,1,&size);
372
y = string_new(size);
376
string_fill(y,(char *) tmp,size);
377
gcry_sexp_release(sexp);
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));
394
#elif defined HAVE_LIBCRYPTO
395
key->dsa_pub = DSA_new();
396
if (key->dsa_pub == NULL) {
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) {
409
#endif /* HAVE_LIBCRYPTO */
413
#ifdef HAVE_LIBGCRYPT
414
sexp = gcry_sexp_find_token(prv->rsa_priv, "n", 0);
418
tmp = gcry_sexp_nth_data(sexp, 1, &size);
419
n = string_new(size);
423
string_fill(n, (char *) tmp, size);
424
gcry_sexp_release(sexp);
426
sexp = gcry_sexp_find_token(prv->rsa_priv, "e", 0);
430
tmp = gcry_sexp_nth_data(sexp, 1, &size);
431
e = string_new(size);
435
string_fill(e, (char *) tmp, size);
436
gcry_sexp_release(sexp);
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) {
450
#elif defined HAVE_LIBCRYPTO
451
key->rsa_pub = RSA_new();
452
if (key->rsa_pub == NULL) {
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) {
464
key->type_c = ssh_type_to_char(prv->type);
468
#ifdef HAVE_LIBGCRYPT
469
gcry_sexp_release(sexp);
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) {
501
#ifdef HAVE_LIBGCRYPT
502
const char *tmp = NULL;
506
sexp = gcry_sexp_find_token(key, "p", 0);
510
tmp = gcry_sexp_nth_data(sexp, 1, &size);
511
p = string_new(size);
515
string_fill(p, (char *) tmp, size);
516
gcry_sexp_release(sexp);
518
sexp = gcry_sexp_find_token(key, "q", 0);
522
tmp = gcry_sexp_nth_data(sexp, 1, &size);
523
q = string_new(size);
527
string_fill(q, (char *) tmp, size);
528
gcry_sexp_release(sexp);
530
sexp = gcry_sexp_find_token(key, "g", 0);
534
tmp = gcry_sexp_nth_data(sexp, 1, &size);
535
g = string_new(size);
539
string_fill(g, (char *) tmp, size);
540
gcry_sexp_release(sexp);
542
sexp = gcry_sexp_find_token(key, "y", 0);
546
tmp = gcry_sexp_nth_data(sexp, 1, &size);
547
n = string_new(size);
551
string_fill(n, (char *) tmp, size);
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) {
561
#endif /* HAVE_LIBCRYPTO */
562
if (buffer_add_ssh_string(buffer, p) < 0) {
565
if (buffer_add_ssh_string(buffer, q) < 0) {
568
if (buffer_add_ssh_string(buffer, g) < 0) {
571
if (buffer_add_ssh_string(buffer, n) < 0) {
577
#ifdef HAVE_LIBGCRYPT
578
gcry_sexp_release(sexp);
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) {
604
#ifdef HAVE_LIBGCRYPT
609
sexp = gcry_sexp_find_token(key, "n", 0);
613
tmp = gcry_sexp_nth_data(sexp, 1, &size);
614
n = string_new(size);
618
string_fill(n, (char *) tmp, size);
619
gcry_sexp_release(sexp);
621
sexp = gcry_sexp_find_token(key, "e", 0);
625
tmp = gcry_sexp_nth_data(sexp, 1, &size);
626
e = string_new(size);
630
string_fill(e, (char *) tmp, size);
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) {
640
if (buffer_add_ssh_string(buffer, e) < 0) {
643
if (buffer_add_ssh_string(buffer, n) < 0) {
649
#ifdef HAVE_LIBGCRYPT
650
gcry_sexp_release(sexp);
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
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;
676
type = string_from_char(key->type_c);
681
if (buffer_add_ssh_string(buf, type) < 0) {
687
if (dsa_public_to_string(key->dsa_pub, buf) < 0) {
693
if (rsa_public_to_string(key->rsa_pub, buf) < 0) {
699
ret = string_new(buffer_get_len(buf));
704
string_fill(ret, buffer_get(buf), buffer_get_len(buf));
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;
720
#ifdef HAVE_LIBGCRYPT
721
const char *r = NULL;
722
const char *s = NULL;
725
#elif defined HAVE_LIBCRYPTO
730
tmpbuf = buffer_new();
731
if (tmpbuf == NULL) {
735
tmp = string_from_char(ssh_type_to_char(sign->type));
740
if (buffer_add_ssh_string(tmpbuf, tmp) < 0) {
749
#ifdef HAVE_LIBGCRYPT
750
sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0);
755
r = gcry_sexp_nth_data(sexp, 1, &size);
756
if (*r == 0) { /* libgcrypt put 0 when first bit is set */
760
memcpy(buffer, r + size - 20, 20);
761
gcry_sexp_release(sexp);
763
sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0);
768
s = gcry_sexp_nth_data(sexp,1,&size);
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);
781
s = make_bignum_string(sign->dsa_sign->s);
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);
793
#endif /* HAVE_LIBCRYPTO */
800
string_fill(rs, buffer, 40);
801
rc = buffer_add_ssh_string(tmpbuf, rs);
811
#ifdef HAVE_LIBGCRYPT
812
sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0);
817
s = gcry_sexp_nth_data(sexp,1,&size);
822
rs = string_new(size);
828
string_fill(rs, (char *) s, size);
829
rc = buffer_add_ssh_string(tmpbuf, rs);
830
gcry_sexp_release(sexp);
836
#elif defined HAVE_LIBCRYPTO
837
if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) {
845
str = string_new(buffer_get_len(tmpbuf));
850
string_fill(str, buffer_get(tmpbuf), buffer_get_len(tmpbuf));
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;
868
#ifdef HAVE_LIBGCRYPT
870
#elif defined HAVE_LIBCRYPTO
876
sign = malloc(sizeof(SIGNATURE));
878
ssh_set_error(session, SSH_FATAL, "Not enough space");
882
tmpbuf = buffer_new();
883
if (tmpbuf == NULL) {
884
ssh_set_error(session, SSH_FATAL, "Not enough space");
885
signature_free(sign);
889
if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature)) < 0) {
890
signature_free(sign);
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);
903
type_c = string_to_char(type_s);
905
if (type_c == NULL) {
906
signature_free(sign);
910
type = ssh_type_from_name(type_c);
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);
921
switch(needed_type) {
923
rs = buffer_get_ssh_string(tmpbuf);
926
/* 40 is the dual signature blob len. */
927
if (rs == NULL || string_len(rs) != 40) {
929
signature_free(sign);
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)) {
939
signature_free(sign);
942
#elif defined HAVE_LIBCRYPTO
945
if (r == NULL || s == NULL) {
949
signature_free(sign);
953
string_fill(r, string_data(rs), 20);
954
string_fill(s, (char *)string_data(rs) + 20, 20);
961
signature_free(sign);
964
sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */
965
sig->s = make_string_bn(s);
969
if (sig->r == NULL || sig->s == NULL) {
972
signature_free(sign);
978
ssh_print_hexa("r", string_data(rs), 20);
979
ssh_print_hexa("s", (const unsigned char *)string_data(rs) + 20, 20);
983
sign->type = TYPE_DSS;
984
sign->dsa_sign = sig;
988
e = buffer_get_ssh_string(tmpbuf);
991
signature_free(sign);
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);
1002
signature_free(sign);
1003
ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d",
1009
ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d",
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);
1021
sign->rsa_sign = sig;
1022
#elif defined HAVE_LIBCRYPTO
1027
ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len);
1028
ssh_print_hexa("RSA signature", string_data(e), len);
1031
#ifdef HAVE_LIBGCRYPT
1043
void signature_free(SIGNATURE *sign) {
1048
switch(sign->type) {
1050
#ifdef HAVE_LIBGCRYPT
1051
gcry_sexp_release(sign->dsa_sign);
1052
#elif defined HAVE_LIBCRYPTO
1053
DSA_SIG_free(sign->dsa_sign);
1058
#ifdef HAVE_LIBGCRYPT
1059
gcry_sexp_release(sign->rsa_sign);
1060
#elif defined HAVE_LIBCRYPTO
1061
SAFE_FREE(sign->rsa_sign);
1065
/* FIXME Passing NULL segfaults */
1067
ssh_log(NULL, SSH_LOG_RARE, "Freeing a signature with no type!\n"); */
1074
#ifdef HAVE_LIBCRYPTO
1076
* Maybe the missing function from libcrypto
1078
* I think now, maybe it's a bad idea to name it has it should have be
1079
* named in libcrypto
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;
1086
buffer = malloc(RSA_size(privkey));
1087
if (buffer == NULL) {
1091
if (RSA_sign(NID_sha1, payload, len, buffer, &size, privkey) == 0) {
1096
sign = string_new(size);
1102
string_fill(sign, buffer, size);
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;
1117
if (session->current_crypto) {
1118
crypto = session->current_crypto;
1120
crypto = session->next_crypto;
1123
/* prepend session identifier */
1124
session_id = string_new(SHA_DIGEST_LEN);
1125
if (session_id == NULL) {
1128
string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);
1130
sigbuf = buffer_new();
1131
if (sigbuf == NULL) {
1132
string_free(session_id);
1136
if (buffer_add_ssh_string(sigbuf, session_id) < 0) {
1137
buffer_free(sigbuf);
1138
string_free(session_id);
1141
string_free(session_id);
1143
/* append out buffer */
1144
if (buffer_add_buffer(sigbuf, buf) < 0) {
1145
buffer_free(sigbuf);
1149
/* create signature */
1150
signature = agent_sign_data(session, sigbuf, publickey);
1152
buffer_free(sigbuf);
1159
* This function concats in a buffer the values needed to do a signature
1161
ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service) {
1163
The value of 'signature' is a signature by the corresponding private
1164
key over the following data, in the following order:
1166
string session identifier
1167
byte SSH_MSG_USERAUTH_REQUEST
1172
string public key algorithm name
1173
string public key to be used for authentication
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);
1187
buffer = buffer_new();
1188
if (buffer == NULL) {
1191
session_id = string_new(SHA_DIGEST_LEN);
1192
if (session_id == NULL) {
1193
buffer_free(buffer);
1197
string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN);
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);
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);
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;
1234
#ifdef HAVE_LIBGCRYPT
1235
gcry_sexp_t gcryhash;
1238
session_str = string_new(SHA_DIGEST_LEN);
1239
if (session_str == NULL) {
1242
string_fill(session_str, crypto->session_id, SHA_DIGEST_LEN);
1246
string_free(session_str);
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);
1257
ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN);
1260
sign = malloc(sizeof(SIGNATURE));
1265
switch(privatekey->type) {
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);
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);
1284
ssh_print_bignum("r", sign->dsa_sign->r);
1285
ssh_print_bignum("s", sign->dsa_sign->s);
1287
#endif /* HAVE_LIBCRYPTO */
1288
sign->rsa_sign = NULL;
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);
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);
1309
sign->dsa_sign = NULL;
1312
signature_free(sign);
1315
#ifdef HAVE_LIBGCRYPT
1316
gcry_sexp_release(gcryhash);
1319
sign->type = privatekey->type;
1321
signature = signature_to_string(sign);
1322
signature_free(sign);
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);
1331
#ifdef HAVE_LIBGCRYPT
1332
const char *tmp = NULL;
1333
gcry_sexp_t ret_sexp;
1334
gcry_sexp_t data_sexp;
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");
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");
1347
gcry_sexp_release(data_sexp);
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);
1355
tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
1361
str = string_new(size);
1363
ssh_set_error(session, SSH_FATAL, "Not enough space");
1364
gcry_sexp_release(data_sexp);
1365
gcry_sexp_release(ret_sexp);
1368
string_fill(str, tmp, size);
1370
gcry_sexp_release(data_sexp);
1371
gcry_sexp_release(ret_sexp);
1372
#elif defined HAVE_LIBCRYPTO
1373
size = RSA_size(key->rsa_pub);
1375
str = string_new(size);
1377
ssh_set_error(session, SSH_FATAL, "Not enough space");
1381
if (RSA_public_encrypt(len, string_data(data), string_data(str), key->rsa_pub,
1382
RSA_PKCS1_PADDING) < 0) {
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;
1400
#ifdef HAVE_LIBGCRYPT
1401
gcry_sexp_t data_sexp;
1408
sha1_update(ctx,crypto->session_id,SHA_DIGEST_LEN);
1409
sha1_final(hash + 1,ctx);
1413
ssh_print_hexa("Hash being signed with dsa",hash+1,SHA_DIGEST_LEN);
1416
sign = malloc(sizeof(SIGNATURE));
1421
switch(privatekey->type) {
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);
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);
1441
ssh_print_bignum("r",sign->dsa_sign->r);
1442
ssh_print_bignum("s",sign->dsa_sign->s);
1445
#endif /* HAVE_LIBCRYPTO */
1446
sign->rsa_sign = NULL;
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);
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);
1467
sign->dsa_sign = NULL;
1470
signature_free(sign);
1474
#ifdef HAVE_LIBGCRYPT
1475
gcry_sexp_release(data_sexp);
1478
sign->type = privatekey->type;
1480
signature = signature_to_string(sign);
1481
signature_free(sign);
1487
/* vim: set ts=2 sw=2 et cindent: */