keys.c | keys.c | |||
---|---|---|---|---|
skipping to change at line 31 | skipping to change at line 31 | |||
* MA 02111-1307, USA. | * MA 02111-1307, USA. | |||
*/ | */ | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <string.h> | #include <string.h> | |||
#ifdef HAVE_LIBCRYPTO | #ifdef HAVE_LIBCRYPTO | |||
#include <openssl/dsa.h> | #include <openssl/dsa.h> | |||
#include <openssl/rsa.h> | #include <openssl/rsa.h> | |||
#endif | #endif | |||
#include "libssh/priv.h" | #include "libssh/priv.h" | |||
#include "libssh/ssh2.h" | ||||
#include "libssh/server.h" | ||||
#include "libssh/buffer.h" | ||||
#include "libssh/agent.h" | ||||
#include "libssh/session.h" | ||||
#include "libssh/keys.h" | ||||
#include "libssh/dh.h" | ||||
#include "libssh/messages.h" | ||||
/** \addtogroup ssh_auth | /** \addtogroup ssh_auth | |||
* @{ | * @{ | |||
*/ | */ | |||
/* Public key decoding functions */ | /* Public key decoding functions */ | |||
const char *ssh_type_to_char(int type) { | const char *ssh_type_to_char(int type) { | |||
switch (type) { | switch (type) { | |||
case TYPE_DSS: | case TYPE_DSS: | |||
return "ssh-dss"; | return "ssh-dss"; | |||
skipping to change at line 68 | skipping to change at line 76 | |||
return TYPE_RSA1; | return TYPE_RSA1; | |||
} else if (strcmp(name, "ssh-rsa") == 0) { | } else if (strcmp(name, "ssh-rsa") == 0) { | |||
return TYPE_RSA; | return TYPE_RSA; | |||
} else if (strcmp(name, "ssh-dss") == 0) { | } else if (strcmp(name, "ssh-dss") == 0) { | |||
return TYPE_DSS; | return TYPE_DSS; | |||
} | } | |||
return -1; | return -1; | |||
} | } | |||
PUBLIC_KEY *publickey_make_dss(SSH_SESSION *session, BUFFER *buffer) { | ssh_public_key publickey_make_dss(ssh_session session, ssh_buffer buffer) { | |||
STRING *p = NULL; | ssh_string p = NULL; | |||
STRING *q = NULL; | ssh_string q = NULL; | |||
STRING *g = NULL; | ssh_string g = NULL; | |||
STRING *pubkey = NULL; | ssh_string pubkey = NULL; | |||
PUBLIC_KEY *key = NULL; | ssh_public_key key = NULL; | |||
key = malloc(sizeof(PUBLIC_KEY)); | key = malloc(sizeof(struct ssh_public_key_struct)); | |||
if (key == NULL) { | if (key == NULL) { | |||
buffer_free(buffer); | buffer_free(buffer); | |||
return NULL; | return NULL; | |||
} | } | |||
key->type = TYPE_DSS; | key->type = TYPE_DSS; | |||
key->type_c = ssh_type_to_char(key->type); | key->type_c = ssh_type_to_char(key->type); | |||
p = buffer_get_ssh_string(buffer); | p = buffer_get_ssh_string(buffer); | |||
q = buffer_get_ssh_string(buffer); | q = buffer_get_ssh_string(buffer); | |||
skipping to change at line 99 | skipping to change at line 107 | |||
buffer_free(buffer); /* we don't need it anymore */ | buffer_free(buffer); /* we don't need it anymore */ | |||
if (p == NULL || q == NULL || g == NULL || pubkey == NULL) { | if (p == NULL || q == NULL || g == NULL || pubkey == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Invalid DSA public key"); | ssh_set_error(session, SSH_FATAL, "Invalid DSA public key"); | |||
goto error; | goto error; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_build(&key->dsa_pub, NULL, | gcry_sexp_build(&key->dsa_pub, NULL, | |||
"(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", | "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", | |||
string_len(p), p->string, | string_len(p), string_data(p), | |||
string_len(q), q->string, | string_len(q), string_data(q), | |||
string_len(g), g->string, | string_len(g), string_data(g), | |||
string_len(pubkey), pubkey->string); | string_len(pubkey), string_data(pubkey)); | |||
if (key->dsa_pub == NULL) { | if (key->dsa_pub == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
key->dsa_pub = DSA_new(); | key->dsa_pub = DSA_new(); | |||
if (key->dsa_pub == NULL) { | if (key->dsa_pub == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
key->dsa_pub->p = make_string_bn(p); | key->dsa_pub->p = make_string_bn(p); | |||
skipping to change at line 154 | skipping to change at line 162 | |||
string_free(q); | string_free(q); | |||
string_burn(g); | string_burn(g); | |||
string_free(g); | string_free(g); | |||
string_burn(pubkey); | string_burn(pubkey); | |||
string_free(pubkey); | string_free(pubkey); | |||
publickey_free(key); | publickey_free(key); | |||
return NULL; | return NULL; | |||
} | } | |||
PUBLIC_KEY *publickey_make_rsa(SSH_SESSION *session, BUFFER *buffer, | ssh_public_key publickey_make_rsa(ssh_session session, ssh_buffer buffer, | |||
int type) { | int type) { | |||
STRING *e = NULL; | ssh_string e = NULL; | |||
STRING *n = NULL; | ssh_string n = NULL; | |||
PUBLIC_KEY *key = NULL; | ssh_public_key key = NULL; | |||
key = malloc(sizeof(PUBLIC_KEY)); | key = malloc(sizeof(struct ssh_public_key_struct)); | |||
if (key == NULL) { | if (key == NULL) { | |||
buffer_free(buffer); | buffer_free(buffer); | |||
return NULL; | return NULL; | |||
} | } | |||
key->type = type; | key->type = type; | |||
key->type_c = ssh_type_to_char(key->type); | key->type_c = ssh_type_to_char(key->type); | |||
e = buffer_get_ssh_string(buffer); | e = buffer_get_ssh_string(buffer); | |||
n = buffer_get_ssh_string(buffer); | n = buffer_get_ssh_string(buffer); | |||
buffer_free(buffer); /* we don't need it anymore */ | buffer_free(buffer); /* we don't need it anymore */ | |||
if(e == NULL || n == NULL) { | if(e == NULL || n == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Invalid RSA public key"); | ssh_set_error(session, SSH_FATAL, "Invalid RSA public key"); | |||
goto error; | goto error; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_build(&key->rsa_pub, NULL, | gcry_sexp_build(&key->rsa_pub, NULL, | |||
"(public-key(rsa(n %b)(e %b)))", | "(public-key(rsa(n %b)(e %b)))", | |||
string_len(n), n->string, | string_len(n), string_data(n), | |||
string_len(e),e->string); | string_len(e),string_data(e)); | |||
if (key->rsa_pub == NULL) { | if (key->rsa_pub == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
#elif HAVE_LIBCRYPTO | #elif HAVE_LIBCRYPTO | |||
key->rsa_pub = RSA_new(); | key->rsa_pub = RSA_new(); | |||
if (key->rsa_pub == NULL) { | if (key->rsa_pub == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
key->rsa_pub->e = make_string_bn(e); | key->rsa_pub->e = make_string_bn(e); | |||
skipping to change at line 221 | skipping to change at line 229 | |||
error: | error: | |||
string_burn(e); | string_burn(e); | |||
string_free(e); | string_free(e); | |||
string_burn(n); | string_burn(n); | |||
string_free(n); | string_free(n); | |||
publickey_free(key); | publickey_free(key); | |||
return NULL; | return NULL; | |||
} | } | |||
void publickey_free(PUBLIC_KEY *key) { | void publickey_free(ssh_public_key key) { | |||
if (key == NULL) { | if (key == NULL) { | |||
return; | return; | |||
} | } | |||
switch(key->type) { | switch(key->type) { | |||
case TYPE_DSS: | case TYPE_DSS: | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_release(key->dsa_pub); | gcry_sexp_release(key->dsa_pub); | |||
#elif HAVE_LIBCRYPTO | #elif HAVE_LIBCRYPTO | |||
DSA_free(key->dsa_pub); | DSA_free(key->dsa_pub); | |||
skipping to change at line 248 | skipping to change at line 256 | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
RSA_free(key->rsa_pub); | RSA_free(key->rsa_pub); | |||
#endif | #endif | |||
break; | break; | |||
default: | default: | |||
break; | break; | |||
} | } | |||
SAFE_FREE(key); | SAFE_FREE(key); | |||
} | } | |||
PUBLIC_KEY *publickey_from_string(SSH_SESSION *session, STRING *pubkey_s) { | ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey | |||
BUFFER *tmpbuf = NULL; | _s) { | |||
STRING *type_s = NULL; | ssh_buffer tmpbuf = NULL; | |||
ssh_string type_s = NULL; | ||||
char *type_c = NULL; | char *type_c = NULL; | |||
int type; | int type; | |||
tmpbuf = buffer_new(); | tmpbuf = buffer_new(); | |||
if (tmpbuf == NULL) { | if (tmpbuf == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
if (buffer_add_data(tmpbuf, pubkey_s->string, string_len(pubkey_s)) < 0) { | if (buffer_add_data(tmpbuf, string_data(pubkey_s), string_len(pubkey_s)) < 0) { | |||
goto error; | goto error; | |||
} | } | |||
type_s = buffer_get_ssh_string(tmpbuf); | type_s = buffer_get_ssh_string(tmpbuf); | |||
if (type_s == NULL) { | if (type_s == NULL) { | |||
ssh_set_error(session,SSH_FATAL,"Invalid public key format"); | ssh_set_error(session,SSH_FATAL,"Invalid public key format"); | |||
goto error; | goto error; | |||
} | } | |||
type_c = string_to_char(type_s); | type_c = string_to_char(type_s); | |||
skipping to change at line 299 | skipping to change at line 307 | |||
error: | error: | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return NULL; | return NULL; | |||
} | } | |||
/** \brief Makes a PUBLIC_KEY object out of a PRIVATE_KEY object | /** \brief Makes a PUBLIC_KEY object out of a PRIVATE_KEY object | |||
* \param prv the Private key | * \param prv the Private key | |||
* \returns the public key | * \returns the public key | |||
* \see publickey_to_string() | * \see publickey_to_string() | |||
*/ | */ | |||
PUBLIC_KEY *publickey_from_privatekey(PRIVATE_KEY *prv) { | ssh_public_key publickey_from_privatekey(ssh_private_key prv) { | |||
PUBLIC_KEY *key = NULL; | ssh_public_key key = NULL; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_t sexp; | gcry_sexp_t sexp; | |||
const char *tmp = NULL; | const char *tmp = NULL; | |||
size_t size; | size_t size; | |||
STRING *p = NULL; | ssh_string p = NULL; | |||
STRING *q = NULL; | ssh_string q = NULL; | |||
STRING *g = NULL; | ssh_string g = NULL; | |||
STRING *y = NULL; | ssh_string y = NULL; | |||
STRING *e = NULL; | ssh_string e = NULL; | |||
STRING *n = NULL; | ssh_string n = NULL; | |||
#endif /* HAVE_LIBGCRYPT */ | #endif /* HAVE_LIBGCRYPT */ | |||
key = malloc(sizeof(PUBLIC_KEY)); | key = malloc(sizeof(struct ssh_public_key_struct)); | |||
if (key == NULL) { | if (key == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
key->type = prv->type; | key->type = prv->type; | |||
switch(key->type) { | switch(key->type) { | |||
case TYPE_DSS: | case TYPE_DSS: | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0); | sexp = gcry_sexp_find_token(prv->dsa_priv, "p", 0); | |||
if (sexp == NULL) { | if (sexp == NULL) { | |||
skipping to change at line 372 | skipping to change at line 380 | |||
tmp = gcry_sexp_nth_data(sexp,1,&size); | tmp = gcry_sexp_nth_data(sexp,1,&size); | |||
y = string_new(size); | y = string_new(size); | |||
if (y == NULL) { | if (y == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
string_fill(y,(char *) tmp,size); | string_fill(y,(char *) tmp,size); | |||
gcry_sexp_release(sexp); | gcry_sexp_release(sexp); | |||
gcry_sexp_build(&key->dsa_pub, NULL, | gcry_sexp_build(&key->dsa_pub, NULL, | |||
"(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", | "(public-key(dsa(p %b)(q %b)(g %b)(y %b)))", | |||
string_len(p), p->string, | string_len(p), string_data(p), | |||
string_len(q), q->string, | string_len(q), string_data(q), | |||
string_len(g), g->string, | string_len(g), string_data(g), | |||
string_len(y), y->string); | string_len(y), string_data(y)); | |||
string_burn(p); | string_burn(p); | |||
string_free(p); | string_free(p); | |||
string_burn(q); | string_burn(q); | |||
string_free(q); | string_free(q); | |||
string_burn(g); | string_burn(g); | |||
string_free(g); | string_free(g); | |||
string_burn(y); | string_burn(y); | |||
string_free(y); | string_free(y); | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
skipping to change at line 431 | skipping to change at line 439 | |||
tmp = gcry_sexp_nth_data(sexp, 1, &size); | tmp = gcry_sexp_nth_data(sexp, 1, &size); | |||
e = string_new(size); | e = string_new(size); | |||
if (e == NULL) { | if (e == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
string_fill(e, (char *) tmp, size); | string_fill(e, (char *) tmp, size); | |||
gcry_sexp_release(sexp); | gcry_sexp_release(sexp); | |||
gcry_sexp_build(&key->rsa_pub, NULL, | gcry_sexp_build(&key->rsa_pub, NULL, | |||
"(public-key(rsa(n %b)(e %b)))", | "(public-key(rsa(n %b)(e %b)))", | |||
string_len(n), n->string, | string_len(n), string_data(n), | |||
string_len(e), e->string); | string_len(e), string_data(e)); | |||
if (key->rsa_pub == NULL) { | if (key->rsa_pub == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
string_burn(e); | string_burn(e); | |||
string_free(e); | string_free(e); | |||
string_burn(n); | string_burn(n); | |||
string_free(n); | string_free(n); | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
key->rsa_pub = RSA_new(); | key->rsa_pub = RSA_new(); | |||
skipping to change at line 481 | skipping to change at line 489 | |||
string_free(e); | string_free(e); | |||
string_burn(n); | string_burn(n); | |||
string_free(n); | string_free(n); | |||
#endif | #endif | |||
publickey_free(key); | publickey_free(key); | |||
return NULL; | return NULL; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
static int dsa_public_to_string(gcry_sexp_t key, BUFFER *buffer) { | static int dsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) { | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
static int dsa_public_to_string(DSA *key, BUFFER *buffer) { | static int dsa_public_to_string(DSA *key, ssh_buffer buffer) { | |||
#endif | #endif | |||
STRING *p = NULL; | ssh_string p = NULL; | |||
STRING *q = NULL; | ssh_string q = NULL; | |||
STRING *g = NULL; | ssh_string g = NULL; | |||
STRING *n = NULL; | ssh_string n = NULL; | |||
int rc = -1; | int rc = -1; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
const char *tmp = NULL; | const char *tmp = NULL; | |||
size_t size; | size_t size; | |||
gcry_sexp_t sexp; | gcry_sexp_t sexp; | |||
sexp = gcry_sexp_find_token(key, "p", 0); | sexp = gcry_sexp_find_token(key, "p", 0); | |||
if (sexp == NULL) { | if (sexp == NULL) { | |||
skipping to change at line 585 | skipping to change at line 593 | |||
string_free(q); | string_free(q); | |||
string_burn(g); | string_burn(g); | |||
string_free(g); | string_free(g); | |||
string_burn(n); | string_burn(n); | |||
string_free(n); | string_free(n); | |||
return rc; | return rc; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
static int rsa_public_to_string(gcry_sexp_t key, BUFFER *buffer) { | static int rsa_public_to_string(gcry_sexp_t key, ssh_buffer buffer) { | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
static int rsa_public_to_string(RSA *key, BUFFER *buffer) { | static int rsa_public_to_string(RSA *key, ssh_buffer buffer) { | |||
#endif | #endif | |||
STRING *e = NULL; | ssh_string e = NULL; | |||
STRING *n = NULL; | ssh_string n = NULL; | |||
int rc = -1; | int rc = -1; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
const char *tmp; | const char *tmp; | |||
size_t size; | size_t size; | |||
gcry_sexp_t sexp; | gcry_sexp_t sexp; | |||
sexp = gcry_sexp_find_token(key, "n", 0); | sexp = gcry_sexp_find_token(key, "n", 0); | |||
if (sexp == NULL) { | if (sexp == NULL) { | |||
skipping to change at line 657 | skipping to change at line 665 | |||
string_free(n); | string_free(n); | |||
return rc; | return rc; | |||
} | } | |||
/** \brief makes a SSH String out of a PUBLIC_KEY object | /** \brief makes a SSH String out of a PUBLIC_KEY object | |||
* \param key the public key | * \param key the public key | |||
* \returns a SSH String containing the public key | * \returns a SSH String containing the public key | |||
* \see string_free() | * \see string_free() | |||
*/ | */ | |||
STRING *publickey_to_string(PUBLIC_KEY *key) { | ssh_string publickey_to_string(ssh_public_key key) { | |||
STRING *type = NULL; | ssh_string type = NULL; | |||
STRING *ret = NULL; | ssh_string ret = NULL; | |||
BUFFER *buf = NULL; | ssh_buffer buf = NULL; | |||
buf = buffer_new(); | buf = buffer_new(); | |||
if (buf == NULL) { | if (buf == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
type = string_from_char(key->type_c); | type = string_from_char(key->type_c); | |||
if (type == NULL) { | if (type == NULL) { | |||
goto error; | goto error; | |||
} | } | |||
skipping to change at line 704 | skipping to change at line 712 | |||
string_fill(ret, buffer_get(buf), buffer_get_len(buf)); | string_fill(ret, buffer_get(buf), buffer_get_len(buf)); | |||
error: | error: | |||
buffer_free(buf); | buffer_free(buf); | |||
string_free(type); | string_free(type); | |||
return ret; | return ret; | |||
} | } | |||
/* Signature decoding functions */ | /* Signature decoding functions */ | |||
static STRING *signature_to_string(SIGNATURE *sign) { | static ssh_string signature_to_string(SIGNATURE *sign) { | |||
unsigned char buffer[40] = {0}; | unsigned char buffer[40] = {0}; | |||
BUFFER *tmpbuf = NULL; | ssh_buffer tmpbuf = NULL; | |||
STRING *str = NULL; | ssh_string str = NULL; | |||
STRING *tmp = NULL; | ssh_string tmp = NULL; | |||
STRING *rs = NULL; | ssh_string rs = NULL; | |||
int rc = -1; | int rc = -1; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
const char *r = NULL; | const char *r = NULL; | |||
const char *s = NULL; | const char *s = NULL; | |||
gcry_sexp_t sexp; | gcry_sexp_t sexp; | |||
size_t size = 0; | size_t size = 0; | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
STRING *r = NULL; | ssh_string r = NULL; | |||
STRING *s = NULL; | ssh_string s = NULL; | |||
#endif | #endif | |||
tmpbuf = buffer_new(); | tmpbuf = buffer_new(); | |||
if (tmpbuf == NULL) { | if (tmpbuf == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
tmp = string_from_char(ssh_type_to_char(sign->type)); | tmp = string_from_char(ssh_type_to_char(sign->type)); | |||
if (tmp == NULL) { | if (tmp == NULL) { | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
skipping to change at line 779 | skipping to change at line 787 | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return NULL; | return NULL; | |||
} | } | |||
s = make_bignum_string(sign->dsa_sign->s); | s = make_bignum_string(sign->dsa_sign->s); | |||
if (s == NULL) { | if (s == NULL) { | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
string_free(r); | string_free(r); | |||
return NULL; | return NULL; | |||
} | } | |||
memcpy(buffer, r->string + string_len(r) - 20, 20); | memcpy(buffer, (char *)string_data(r) + string_len(r) - 20, 20); | |||
memcpy(buffer + 20, s->string + string_len(s) - 20, 20); | memcpy(buffer + 20, (char *)string_data(s) + string_len(s) - 20, 20); | |||
string_free(r); | string_free(r); | |||
string_free(s); | string_free(s); | |||
#endif /* HAVE_LIBCRYPTO */ | #endif /* HAVE_LIBCRYPTO */ | |||
rs = string_new(40); | rs = string_new(40); | |||
if (rs == NULL) { | if (rs == NULL) { | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return NULL; | return NULL; | |||
} | } | |||
skipping to change at line 848 | skipping to change at line 856 | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return NULL; | return NULL; | |||
} | } | |||
string_fill(str, buffer_get(tmpbuf), buffer_get_len(tmpbuf)); | string_fill(str, buffer_get(tmpbuf), buffer_get_len(tmpbuf)); | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return str; | return str; | |||
} | } | |||
/* TODO : split this function in two so it becomes smaller */ | /* TODO : split this function in two so it becomes smaller */ | |||
SIGNATURE *signature_from_string(SSH_SESSION *session, STRING *signature, | SIGNATURE *signature_from_string(ssh_session session, ssh_string signature, | |||
PUBLIC_KEY *pubkey, int needed_type) { | ssh_public_key pubkey, int needed_type) { | |||
SIGNATURE *sign = NULL; | SIGNATURE *sign = NULL; | |||
BUFFER *tmpbuf = NULL; | ssh_buffer tmpbuf = NULL; | |||
STRING *rs = NULL; | ssh_string rs = NULL; | |||
STRING *type_s = NULL; | ssh_string type_s = NULL; | |||
STRING *e = NULL; | ssh_string e = NULL; | |||
char *type_c = NULL; | char *type_c = NULL; | |||
int type; | int type; | |||
int len; | int len; | |||
int rsalen; | int rsalen; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_t sig; | gcry_sexp_t sig; | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
DSA_SIG *sig = NULL; | DSA_SIG *sig = NULL; | |||
STRING *r = NULL; | ssh_string r = NULL; | |||
STRING *s = NULL; | ssh_string s = NULL; | |||
#endif | #endif | |||
sign = malloc(sizeof(SIGNATURE)); | sign = malloc(sizeof(SIGNATURE)); | |||
if (sign == NULL) { | if (sign == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Not enough space"); | ssh_set_error(session, SSH_FATAL, "Not enough space"); | |||
return NULL; | return NULL; | |||
} | } | |||
tmpbuf = buffer_new(); | tmpbuf = buffer_new(); | |||
if (tmpbuf == NULL) { | if (tmpbuf == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Not enough space"); | ssh_set_error(session, SSH_FATAL, "Not enough space"); | |||
signature_free(sign); | signature_free(sign); | |||
return NULL; | return NULL; | |||
} | } | |||
if (buffer_add_data(tmpbuf, signature->string, string_len(signature)) < 0 ) { | if (buffer_add_data(tmpbuf, string_data(signature), string_len(signature) ) < 0) { | |||
signature_free(sign); | signature_free(sign); | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
return NULL; | return NULL; | |||
} | } | |||
type_s = buffer_get_ssh_string(tmpbuf); | type_s = buffer_get_ssh_string(tmpbuf); | |||
if (type_s == NULL) { | if (type_s == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Invalid signature packet"); | ssh_set_error(session, SSH_FATAL, "Invalid signature packet"); | |||
signature_free(sign); | signature_free(sign); | |||
buffer_free(tmpbuf); | buffer_free(tmpbuf); | |||
skipping to change at line 928 | skipping to change at line 936 | |||
if (rs == NULL || string_len(rs) != 40) { | if (rs == NULL || string_len(rs) != 40) { | |||
string_free(rs); | string_free(rs); | |||
signature_free(sign); | signature_free(sign); | |||
return NULL; | return NULL; | |||
} | } | |||
/* we make use of strings (because we have all-made functions to conv ert | /* we make use of strings (because we have all-made functions to conv ert | |||
* them to bignums (ou pas ;) */ | * them to bignums (ou pas ;) */ | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))", | if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))", | |||
20 ,rs->string, 20, rs->string + 20)) { | 20 ,string_data(rs), 20,(unsigned char *)string_data(rs) + 20)) { | |||
string_free(rs); | string_free(rs); | |||
signature_free(sign); | signature_free(sign); | |||
return NULL; | return NULL; | |||
} | } | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
r = string_new(20); | r = string_new(20); | |||
s = string_new(20); | s = string_new(20); | |||
if (r == NULL || s == NULL) { | if (r == NULL || s == NULL) { | |||
string_free(r); | string_free(r); | |||
string_free(s); | string_free(s); | |||
string_free(rs); | string_free(rs); | |||
signature_free(sign); | signature_free(sign); | |||
return NULL; | return NULL; | |||
} | } | |||
string_fill(r, rs->string, 20); | string_fill(r, string_data(rs), 20); | |||
string_fill(s, rs->string + 20, 20); | string_fill(s, (char *)string_data(rs) + 20, 20); | |||
sig = DSA_SIG_new(); | sig = DSA_SIG_new(); | |||
if (sig == NULL) { | if (sig == NULL) { | |||
string_free(r); | string_free(r); | |||
string_free(s); | string_free(s); | |||
string_free(rs); | string_free(rs); | |||
signature_free(sign); | signature_free(sign); | |||
return NULL; | return NULL; | |||
} | } | |||
sig->r = make_string_bn(r); /* is that really portable ? Openssh's ha ck isn't better */ | sig->r = make_string_bn(r); /* is that really portable ? Openssh's ha ck isn't better */ | |||
skipping to change at line 1006 | skipping to change at line 1014 | |||
return NULL; | return NULL; | |||
} | } | |||
if (len < rsalen) { | if (len < rsalen) { | |||
ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d", | ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d", | |||
len, rsalen); | len, rsalen); | |||
} | } | |||
sign->type = TYPE_RSA; | sign->type = TYPE_RSA; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))", | if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))", | |||
string_len(e), e->string)) { | string_len(e), string_data(e))) { | |||
signature_free(sign); | signature_free(sign); | |||
string_free(e); | string_free(e); | |||
return NULL; | return NULL; | |||
} | } | |||
sign->rsa_sign = sig; | sign->rsa_sign = sig; | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
sign->rsa_sign = e; | sign->rsa_sign = e; | |||
#endif | #endif | |||
skipping to change at line 1072 | skipping to change at line 1080 | |||
SAFE_FREE(sign); | SAFE_FREE(sign); | |||
} | } | |||
#ifdef HAVE_LIBCRYPTO | #ifdef HAVE_LIBCRYPTO | |||
/* | /* | |||
* Maybe the missing function from libcrypto | * Maybe the missing function from libcrypto | |||
* | * | |||
* I think now, maybe it's a bad idea to name it has it should have be | * I think now, maybe it's a bad idea to name it has it should have be | |||
* named in libcrypto | * named in libcrypto | |||
*/ | */ | |||
static STRING *RSA_do_sign(const unsigned char *payload, int len, RSA *priv | static ssh_string RSA_do_sign(const unsigned char *payload, int len, RSA *p | |||
key) { | rivkey) { | |||
STRING *sign = NULL; | ssh_string sign = NULL; | |||
unsigned char *buffer = NULL; | unsigned char *buffer = NULL; | |||
unsigned int size; | unsigned int size; | |||
buffer = malloc(RSA_size(privkey)); | buffer = malloc(RSA_size(privkey)); | |||
if (buffer == NULL) { | if (buffer == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
if (RSA_sign(NID_sha1, payload, len, buffer, &size, privkey) == 0) { | if (RSA_sign(NID_sha1, payload, len, buffer, &size, privkey) == 0) { | |||
SAFE_FREE(buffer); | SAFE_FREE(buffer); | |||
skipping to change at line 1101 | skipping to change at line 1109 | |||
} | } | |||
string_fill(sign, buffer, size); | string_fill(sign, buffer, size); | |||
SAFE_FREE(buffer); | SAFE_FREE(buffer); | |||
return sign; | return sign; | |||
} | } | |||
#endif | #endif | |||
#ifndef _WIN32 | #ifndef _WIN32 | |||
STRING *ssh_do_sign_with_agent(struct ssh_session *session, | ssh_string ssh_do_sign_with_agent(ssh_session session, | |||
struct buffer_struct *buf, struct public_key_struct *publickey) { | struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) | |||
struct buffer_struct *sigbuf = NULL; | { | |||
struct string_struct *signature = NULL; | struct ssh_buffer_struct *sigbuf = NULL; | |||
struct string_struct *session_id = NULL; | struct ssh_string_struct *signature = NULL; | |||
struct ssh_string_struct *session_id = NULL; | ||||
struct ssh_crypto_struct *crypto = NULL; | struct ssh_crypto_struct *crypto = NULL; | |||
if (session->current_crypto) { | if (session->current_crypto) { | |||
crypto = session->current_crypto; | crypto = session->current_crypto; | |||
} else { | } else { | |||
crypto = session->next_crypto; | crypto = session->next_crypto; | |||
} | } | |||
/* prepend session identifier */ | /* prepend session identifier */ | |||
session_id = string_new(SHA_DIGEST_LEN); | session_id = string_new(SHA_DIGEST_LEN); | |||
skipping to change at line 1150 | skipping to change at line 1158 | |||
/* create signature */ | /* create signature */ | |||
signature = agent_sign_data(session, sigbuf, publickey); | signature = agent_sign_data(session, sigbuf, publickey); | |||
buffer_free(sigbuf); | buffer_free(sigbuf); | |||
return signature; | return signature; | |||
} | } | |||
#endif /* _WIN32 */ | #endif /* _WIN32 */ | |||
/* | /* | |||
* This function concats in a buffer the values needed to do a signature | ||||
* verification. */ | ||||
ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, | ||||
char *service) { | ||||
/* | ||||
The value of 'signature' is a signature by the corresponding private | ||||
key over the following data, in the following order: | ||||
string session identifier | ||||
byte SSH_MSG_USERAUTH_REQUEST | ||||
string user name | ||||
string service name | ||||
string "publickey" | ||||
boolean TRUE | ||||
string public key algorithm name | ||||
string public key to be used for authentication | ||||
*/ | ||||
struct ssh_crypto_struct *crypto = session->current_crypto ? session | ||||
->current_crypto : | ||||
session->next_crypto; | ||||
ssh_buffer buffer = NULL; | ||||
ssh_string session_id = NULL; | ||||
uint8_t type = SSH2_MSG_USERAUTH_REQUEST; | ||||
ssh_string username = string_from_char(msg->auth_request.username); | ||||
ssh_string servicename = string_from_char(service); | ||||
ssh_string method = string_from_char("publickey"); | ||||
uint8_t has_sign = 1; | ||||
ssh_string algo = string_from_char(msg->auth_request.public_key->type_c); | ||||
ssh_string publickey = publickey_to_string(msg->auth_request.public_key); | ||||
buffer = buffer_new(); | ||||
if (buffer == NULL) { | ||||
goto error; | ||||
} | ||||
session_id = string_new(SHA_DIGEST_LEN); | ||||
if (session_id == NULL) { | ||||
buffer_free(buffer); | ||||
buffer = NULL; | ||||
goto error; | ||||
} | ||||
string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN); | ||||
if(buffer_add_ssh_string(buffer, session_id) < 0 || | ||||
buffer_add_u8(buffer, type) < 0 || | ||||
buffer_add_ssh_string(buffer, username) < 0 || | ||||
buffer_add_ssh_string(buffer, servicename) < 0 || | ||||
buffer_add_ssh_string(buffer, method) < 0 || | ||||
buffer_add_u8(buffer, has_sign) < 0 || | ||||
buffer_add_ssh_string(buffer, algo) < 0 || | ||||
buffer_add_ssh_string(buffer, publickey) < 0) { | ||||
buffer_free(buffer); | ||||
buffer = NULL; | ||||
goto error; | ||||
} | ||||
error: | ||||
if(session_id) string_free(session_id); | ||||
if(username) string_free(username); | ||||
if(servicename) string_free(servicename); | ||||
if(method) string_free(method); | ||||
if(algo) string_free(algo); | ||||
if(publickey) string_free(publickey); | ||||
return buffer; | ||||
} | ||||
/* | ||||
* This function signs the session id (known as H) as a string then | * This function signs the session id (known as H) as a string then | |||
* the content of sigbuf */ | * the content of sigbuf */ | |||
STRING *ssh_do_sign(SSH_SESSION *session, BUFFER *sigbuf, | ssh_string ssh_do_sign(ssh_session session, ssh_buffer sigbuf, | |||
PRIVATE_KEY *privatekey) { | ssh_private_key privatekey) { | |||
CRYPTO *crypto = session->current_crypto ? session->current_crypto : | struct ssh_crypto_struct *crypto = session->current_crypto ? session->cur | |||
rent_crypto : | ||||
session->next_crypto; | session->next_crypto; | |||
unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; | unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; | |||
STRING *session_str = NULL; | ssh_string session_str = NULL; | |||
STRING *signature = NULL; | ssh_string signature = NULL; | |||
SIGNATURE *sign = NULL; | SIGNATURE *sign = NULL; | |||
SHACTX ctx = NULL; | SHACTX ctx = NULL; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_t gcryhash; | gcry_sexp_t gcryhash; | |||
#endif | #endif | |||
session_str = string_new(SHA_DIGEST_LEN); | session_str = string_new(SHA_DIGEST_LEN); | |||
if (session_str == NULL) { | if (session_str == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
skipping to change at line 1251 | skipping to change at line 1323 | |||
#endif | #endif | |||
sign->type = privatekey->type; | sign->type = privatekey->type; | |||
signature = signature_to_string(sign); | signature = signature_to_string(sign); | |||
signature_free(sign); | signature_free(sign); | |||
return signature; | return signature; | |||
} | } | |||
STRING *ssh_encrypt_rsa1(SSH_SESSION *session, STRING *data, PUBLIC_KEY *ke | ssh_string ssh_encrypt_rsa1(ssh_session session, ssh_string data, ssh_publi | |||
y) { | c_key key) { | |||
STRING *str = NULL; | ssh_string str = NULL; | |||
size_t len = string_len(data); | size_t len = string_len(data); | |||
size_t size = 0; | size_t size = 0; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
const char *tmp = NULL; | const char *tmp = NULL; | |||
gcry_sexp_t ret_sexp; | gcry_sexp_t ret_sexp; | |||
gcry_sexp_t data_sexp; | gcry_sexp_t data_sexp; | |||
if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))", | if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))", | |||
len, data->string)) { | len, string_data(data))) { | |||
ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); | ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); | |||
return NULL; | return NULL; | |||
} | } | |||
if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) { | if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) { | |||
gcry_sexp_release(data_sexp); | gcry_sexp_release(data_sexp); | |||
ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); | ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error"); | |||
return NULL; | return NULL; | |||
} | } | |||
gcry_sexp_release(data_sexp); | gcry_sexp_release(data_sexp); | |||
skipping to change at line 1305 | skipping to change at line 1377 | |||
gcry_sexp_release(ret_sexp); | gcry_sexp_release(ret_sexp); | |||
#elif defined HAVE_LIBCRYPTO | #elif defined HAVE_LIBCRYPTO | |||
size = RSA_size(key->rsa_pub); | size = RSA_size(key->rsa_pub); | |||
str = string_new(size); | str = string_new(size); | |||
if (str == NULL) { | if (str == NULL) { | |||
ssh_set_error(session, SSH_FATAL, "Not enough space"); | ssh_set_error(session, SSH_FATAL, "Not enough space"); | |||
return NULL; | return NULL; | |||
} | } | |||
if (RSA_public_encrypt(len, data->string, str->string, key->rsa_pub, | if (RSA_public_encrypt(len, string_data(data), string_data(str), key->rsa _pub, | |||
RSA_PKCS1_PADDING) < 0) { | RSA_PKCS1_PADDING) < 0) { | |||
string_free(str); | string_free(str); | |||
return NULL; | return NULL; | |||
} | } | |||
#endif | #endif | |||
return str; | return str; | |||
} | } | |||
/* this function signs the session id */ | /* this function signs the session id */ | |||
STRING *ssh_sign_session_id(SSH_SESSION *session, PRIVATE_KEY *privatekey) | ssh_string ssh_sign_session_id(ssh_session session, ssh_private_key private | |||
{ | key) { | |||
CRYPTO *crypto=session->current_crypto ? session->current_crypto : | struct ssh_crypto_struct *crypto=session->current_crypto ? session-> | |||
current_crypto : | ||||
session->next_crypto; | session->next_crypto; | |||
unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; | unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; | |||
STRING *signature = NULL; | ssh_string signature = NULL; | |||
SIGNATURE *sign = NULL; | SIGNATURE *sign = NULL; | |||
SHACTX ctx = NULL; | SHACTX ctx = NULL; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_sexp_t data_sexp; | gcry_sexp_t data_sexp; | |||
#endif | #endif | |||
ctx = sha1_init(); | ctx = sha1_init(); | |||
if (ctx == NULL) { | if (ctx == NULL) { | |||
return NULL; | return NULL; | |||
} | } | |||
End of changes. 44 change blocks. | ||||
96 lines changed or deleted | 174 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |