diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2011-08-22 11:23:33 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-08-22 11:23:33 +0200 |
commit | ca9b01af991d1e7080bef2bb8c9540538eb0df12 (patch) | |
tree | 366afdfe80e0546e809b849e6f637cfa955cba79 | |
parent | d0d9e6261110e680447c7473bf42072b285c38e9 (diff) | |
download | libssh-ca9b01af991d1e7080bef2bb8c9540538eb0df12.tar.gz libssh-ca9b01af991d1e7080bef2bb8c9540538eb0df12.tar.xz libssh-ca9b01af991d1e7080bef2bb8c9540538eb0df12.zip |
pki: Migrate signature functions to legacy code.
-rw-r--r-- | src/keys.c | 331 | ||||
-rw-r--r-- | src/legacy.c | 85 |
2 files changed, 85 insertions, 331 deletions
@@ -264,337 +264,6 @@ error: return NULL; } -/* Signature decoding functions */ -ssh_string signature_to_string(SIGNATURE *sign) { - unsigned char buffer[40] = {0}; - ssh_buffer tmpbuf = NULL; - ssh_string str = NULL; - ssh_string tmp = NULL; - ssh_string rs = NULL; - int rc = -1; -#ifdef HAVE_LIBGCRYPT - const char *r = NULL; - const char *s = NULL; - gcry_sexp_t sexp; - size_t size = 0; -#elif defined HAVE_LIBCRYPTO - ssh_string r = NULL; - ssh_string s = NULL; -#endif - - tmpbuf = ssh_buffer_new(); - if (tmpbuf == NULL) { - return NULL; - } - - tmp = ssh_string_from_char(ssh_type_to_char(sign->type)); - if (tmp == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - if (buffer_add_ssh_string(tmpbuf, tmp) < 0) { - ssh_buffer_free(tmpbuf); - ssh_string_free(tmp); - return NULL; - } - ssh_string_free(tmp); - - switch(sign->type) { - case SSH_KEYTYPE_DSS: -#ifdef HAVE_LIBGCRYPT - sexp = gcry_sexp_find_token(sign->dsa_sign, "r", 0); - if (sexp == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - r = gcry_sexp_nth_data(sexp, 1, &size); - if (*r == 0) { /* libgcrypt put 0 when first bit is set */ - size--; - r++; - } - memcpy(buffer, r + size - 20, 20); - gcry_sexp_release(sexp); - - sexp = gcry_sexp_find_token(sign->dsa_sign, "s", 0); - if (sexp == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - s = gcry_sexp_nth_data(sexp,1,&size); - if (*s == 0) { - size--; - s++; - } - memcpy(buffer+ 20, s + size - 20, 20); - gcry_sexp_release(sexp); -#elif defined HAVE_LIBCRYPTO - r = make_bignum_string(sign->dsa_sign->r); - if (r == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - s = make_bignum_string(sign->dsa_sign->s); - if (s == NULL) { - ssh_buffer_free(tmpbuf); - ssh_string_free(r); - return NULL; - } - - memcpy(buffer, (char *)ssh_string_data(r) + ssh_string_len(r) - 20, 20); - memcpy(buffer + 20, (char *)ssh_string_data(s) + ssh_string_len(s) - 20, 20); - - ssh_string_free(r); - ssh_string_free(s); -#endif /* HAVE_LIBCRYPTO */ - rs = ssh_string_new(40); - if (rs == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - - ssh_string_fill(rs, buffer, 40); - rc = buffer_add_ssh_string(tmpbuf, rs); - ssh_string_free(rs); - if (rc < 0) { - ssh_buffer_free(tmpbuf); - return NULL; - } - - break; - case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: -#ifdef HAVE_LIBGCRYPT - sexp = gcry_sexp_find_token(sign->rsa_sign, "s", 0); - if (sexp == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - s = gcry_sexp_nth_data(sexp,1,&size); - if (*s == 0) { - size--; - s++; - } - rs = ssh_string_new(size); - if (rs == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - - ssh_string_fill(rs, (char *) s, size); - rc = buffer_add_ssh_string(tmpbuf, rs); - gcry_sexp_release(sexp); - ssh_string_free(rs); - if (rc < 0) { - ssh_buffer_free(tmpbuf); - return NULL; - } -#elif defined HAVE_LIBCRYPTO - if (buffer_add_ssh_string(tmpbuf,sign->rsa_sign) < 0) { - ssh_buffer_free(tmpbuf); - return NULL; - } -#endif - break; - } - - str = ssh_string_new(buffer_get_rest_len(tmpbuf)); - if (str == NULL) { - ssh_buffer_free(tmpbuf); - return NULL; - } - ssh_string_fill(str, buffer_get_rest(tmpbuf), buffer_get_rest_len(tmpbuf)); - ssh_buffer_free(tmpbuf); - - return str; -} - -/* TODO : split this function in two so it becomes smaller */ -SIGNATURE *signature_from_string(ssh_session session, ssh_string signature, - ssh_public_key pubkey, int needed_type) { - SIGNATURE *sign = NULL; - ssh_buffer tmpbuf = NULL; - ssh_string rs = NULL; - ssh_string type_s = NULL; - ssh_string e = NULL; - char *type_c = NULL; - int type; - int len; - int rsalen; -#ifdef HAVE_LIBGCRYPT - gcry_sexp_t sig; -#elif defined HAVE_LIBCRYPTO - DSA_SIG *sig = NULL; - ssh_string r = NULL; - ssh_string s = NULL; -#endif - - sign = malloc(sizeof(SIGNATURE)); - if (sign == NULL) { - ssh_set_error(session, SSH_FATAL, "Not enough space"); - return NULL; - } - - tmpbuf = ssh_buffer_new(); - if (tmpbuf == NULL) { - ssh_set_error(session, SSH_FATAL, "Not enough space"); - signature_free(sign); - return NULL; - } - - if (buffer_add_data(tmpbuf, ssh_string_data(signature), ssh_string_len(signature)) < 0) { - signature_free(sign); - ssh_buffer_free(tmpbuf); - return NULL; - } - - type_s = buffer_get_ssh_string(tmpbuf); - if (type_s == NULL) { - ssh_set_error(session, SSH_FATAL, "Invalid signature packet"); - signature_free(sign); - ssh_buffer_free(tmpbuf); - return NULL; - } - - type_c = ssh_string_to_char(type_s); - ssh_string_free(type_s); - if (type_c == NULL) { - signature_free(sign); - ssh_buffer_free(tmpbuf); - return NULL; - } - type = ssh_type_from_name(type_c); - SAFE_FREE(type_c); - - if (needed_type != type) { - ssh_set_error(session, SSH_FATAL, "Invalid signature type: %s", - ssh_type_to_char(type)); - signature_free(sign); - ssh_buffer_free(tmpbuf); - return NULL; - } - - switch(needed_type) { - case SSH_KEYTYPE_DSS: - rs = buffer_get_ssh_string(tmpbuf); - ssh_buffer_free(tmpbuf); - - /* 40 is the dual signature blob len. */ - if (rs == NULL || ssh_string_len(rs) != 40) { - ssh_string_free(rs); - signature_free(sign); - return NULL; - } - - /* we make use of strings (because we have all-made functions to convert - * them to bignums (ou pas ;) */ -#ifdef HAVE_LIBGCRYPT - if (gcry_sexp_build(&sig, NULL, "(sig-val(dsa(r %b)(s %b)))", - 20 ,ssh_string_data(rs), 20,(unsigned char *)ssh_string_data(rs) + 20)) { - ssh_string_free(rs); - signature_free(sign); - return NULL; - } -#elif defined HAVE_LIBCRYPTO - r = ssh_string_new(20); - s = ssh_string_new(20); - if (r == NULL || s == NULL) { - ssh_string_free(r); - ssh_string_free(s); - ssh_string_free(rs); - signature_free(sign); - return NULL; - } - - ssh_string_fill(r, ssh_string_data(rs), 20); - ssh_string_fill(s, (char *)ssh_string_data(rs) + 20, 20); - - sig = DSA_SIG_new(); - if (sig == NULL) { - ssh_string_free(r); - ssh_string_free(s); - ssh_string_free(rs); - signature_free(sign); - return NULL; - } - sig->r = make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */ - sig->s = make_string_bn(s); - ssh_string_free(r); - ssh_string_free(s); - - if (sig->r == NULL || sig->s == NULL) { - ssh_string_free(rs); - DSA_SIG_free(sig); - signature_free(sign); - return NULL; - } -#endif - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("r", ssh_string_data(rs), 20); - ssh_print_hexa("s", (const unsigned char *)ssh_string_data(rs) + 20, 20); -#endif - ssh_string_free(rs); - - sign->type = SSH_KEYTYPE_DSS; - sign->dsa_sign = sig; - - return sign; - case SSH_KEYTYPE_RSA: - e = buffer_get_ssh_string(tmpbuf); - ssh_buffer_free(tmpbuf); - if (e == NULL) { - signature_free(sign); - return NULL; - } - len = ssh_string_len(e); -#ifdef HAVE_LIBGCRYPT - rsalen = (gcry_pk_get_nbits(pubkey->rsa_pub) + 7) / 8; -#elif defined HAVE_LIBCRYPTO - rsalen = RSA_size(pubkey->rsa_pub); -#endif - if (len > rsalen) { - ssh_string_free(e); - signature_free(sign); - ssh_set_error(session, SSH_FATAL, "Signature too big! %d instead of %d", - len, rsalen); - return NULL; - } - - if (len < rsalen) { - ssh_log(session, SSH_LOG_RARE, "RSA signature len %d < %d", - len, rsalen); - } - sign->type = SSH_KEYTYPE_RSA; -#ifdef HAVE_LIBGCRYPT - if (gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))", - ssh_string_len(e), ssh_string_data(e))) { - signature_free(sign); - ssh_string_free(e); - return NULL; - } - - sign->rsa_sign = sig; -#elif defined HAVE_LIBCRYPTO - sign->rsa_sign = e; -#endif - -#ifdef DEBUG_CRYPTO - ssh_log(session, SSH_LOG_FUNCTIONS, "len e: %d", len); - ssh_print_hexa("RSA signature", ssh_string_data(e), len); -#endif - -#ifdef HAVE_LIBGCRYPT - ssh_string_free(e); -#endif - - return sign; - default: - return NULL; - } - - return NULL; -} - void signature_free(SIGNATURE *sign) { if (sign == NULL) { return; diff --git a/src/legacy.c b/src/legacy.c index 681ed0f..25ae53b 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -429,6 +429,91 @@ ssh_string publickey_to_string(ssh_public_key pubkey) { return key_blob; } + +ssh_string signature_to_string(SIGNATURE *sign) +{ + ssh_signature sig; + ssh_string sig_blob; + int rc; + + if (sign == NULL) { + return NULL; + } + + sig = ssh_signature_new(); + if (sig == NULL) { + return NULL; + } + + sig->type = sign->type; + sig->dsa_sig = sign->dsa_sign; + sig->rsa_sig = sign->rsa_sign; + + rc = ssh_pki_export_signature_blob(sig, &sig_blob); + sig->dsa_sig = NULL; + sig->rsa_sig = NULL; + ssh_signature_free(sig); + if (rc < 0) { + return NULL; + } + + return sig_blob; +} + +SIGNATURE *signature_from_string(ssh_session session, + ssh_string signature, + ssh_public_key pubkey, + int needed_type) +{ + SIGNATURE *sign; + ssh_signature sig; + ssh_key key; + int rc; + + if (session == NULL || signature == NULL || pubkey == NULL) { + return NULL; + } + + key = ssh_key_new(); + if (key == NULL) { + return NULL; + } + + key->type = pubkey->type; + key->type_c = pubkey->type_c; + key->flags = SSH_KEY_FLAG_PUBLIC; + key->dsa = pubkey->dsa_pub; + key->rsa = pubkey->rsa_pub; + + rc = ssh_pki_import_signature_blob(signature, key, &sig); + key->dsa = NULL; + key->rsa = NULL; + ssh_key_free(key); + if (rc < 0) { + return NULL; + } + + if ((enum ssh_keytypes_e)needed_type != sig->type) { + ssh_signature_free(sig); + return NULL; + } + + sign = malloc(sizeof(struct signature_struct)); + if (sign == NULL) { + ssh_signature_free(sig); + return NULL; + } + + sign->type = sig->type; + sign->dsa_sign = sig->dsa_sig; + sig->dsa_sig = NULL; + sign->rsa_sign = sig->rsa_sig; + sig->rsa_sig = NULL; + + ssh_signature_free(sig); + return sign; +} + /**************************************************************************** * SERVER SUPPORT ****************************************************************************/ |