diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2011-09-18 22:04:03 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-10-29 19:58:28 +0200 |
commit | 2c04994443384224161d895d00255b5788e8376d (patch) | |
tree | d07f4eb26408d4e0f8b76d96212e11f23b20f699 /src | |
parent | e799c0ce7d046606d9391d826461c2782f072fa0 (diff) | |
download | libssh-2c04994443384224161d895d00255b5788e8376d.tar.gz libssh-2c04994443384224161d895d00255b5788e8376d.tar.xz libssh-2c04994443384224161d895d00255b5788e8376d.zip |
pki: Add a ssh_key_cmp() function.
Diffstat (limited to 'src')
-rw-r--r-- | src/pki.c | 34 | ||||
-rw-r--r-- | src/pki_crypto.c | 58 | ||||
-rw-r--r-- | src/pki_gcrypt.c | 99 |
3 files changed, 191 insertions, 0 deletions
@@ -257,6 +257,40 @@ int ssh_key_is_private(const ssh_key k) { return (k->flags & SSH_KEY_FLAG_PRIVATE); } +/** + * @brief Compare keys if they are equal. + * + * @param[in] k1 The first key to compare. + * + * @param[in] k2 The second key to compare. + * + * @param[in] what What part or type of the key do you want to compare. + * + * @return 0 if equal, 1 if not. + */ +int ssh_key_cmp(const ssh_key k1, + const ssh_key k2, + enum ssh_keycmp_e what) +{ + if (k1 == NULL || k2 == NULL) { + return 1; + } + + if (k1->type != k2->type) { + ssh_pki_log("key types don't macth!"); + return 1; + } + + if (what == SSH_KEY_CMP_PRIVATE) { + if (!ssh_key_is_private(k1) || + !ssh_key_is_private(k2)) { + return 1; + } + } + + return pki_key_compare(k1, k2, what); +} + ssh_signature ssh_signature_new(void) { struct ssh_signature_struct *sig; diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 850ea66..41505a7 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -267,6 +267,64 @@ int pki_key_generate_dss(ssh_key key, int parameter){ return SSH_OK; } +int pki_key_compare(const ssh_key k1, + const ssh_key k2, + enum ssh_keycmp_e what) +{ + switch (k1->type) { + case SSH_KEYTYPE_DSS: + if (DSA_size(k1->dsa) != DSA_size(k2->dsa)) { + return 1; + } + if (bignum_cmp(k1->dsa->p, k2->dsa->p) != 0) { + return 1; + } + if (bignum_cmp(k1->dsa->q, k2->dsa->q) != 0) { + return 1; + } + if (bignum_cmp(k1->dsa->g, k2->dsa->g) != 0) { + return 1; + } + if (bignum_cmp(k1->dsa->pub_key, k2->dsa->pub_key) != 0) { + return 1; + } + + if (what == SSH_KEY_CMP_PRIVATE) { + if (bignum_cmp(k1->dsa->priv_key, k2->dsa->priv_key) != 0) { + return 1; + } + } + break; + case SSH_KEYTYPE_RSA: + case SSH_KEYTYPE_RSA1: + if (RSA_size(k1->rsa) != RSA_size(k2->rsa)) { + return 1; + } + if (bignum_cmp(k1->rsa->e, k2->rsa->e) != 0) { + return 1; + } + if (bignum_cmp(k1->rsa->n, k2->rsa->n) != 0) { + return 1; + } + + if (what == SSH_KEY_CMP_PRIVATE) { + if (bignum_cmp(k1->rsa->p, k2->rsa->p) != 0) { + return 1; + } + + if (bignum_cmp(k1->rsa->q, k2->rsa->q) != 0) { + return 1; + } + } + break; + case SSH_KEYTYPE_ECDSA: + case SSH_KEYTYPE_UNKNOWN: + return 1; + } + + return 0; +} + ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase, ssh_auth_callback auth_fn, diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index 2bb99d2..6a3a9c6 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -993,6 +993,105 @@ int pki_key_generate_dss(ssh_key key, int parameter){ return pki_key_generate(key, parameter, "dsa", SSH_KEYTYPE_DSS); } +static int _bignum_cmp(const gcry_sexp_t s1, + const gcry_sexp_t s2, + const char *what) +{ + gcry_sexp_t sexp; + bignum b1; + bignum b2; + + sexp = gcry_sexp_find_token(s1, what, 0); + if (sexp == NULL) { + return 1; + } + b1 = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(sexp); + if (b1 == NULL) { + return 1; + } + + sexp = gcry_sexp_find_token(s2, what, 0); + if (sexp == NULL) { + return 1; + } + b2 = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(sexp); + if (b2 == NULL) { + return 1; + } + + if (bignum_cmp(b1, b2) != 0) { + return 1; + } + + return 0; +} + +int pki_key_compare(const ssh_key k1, + const ssh_key k2, + enum ssh_keycmp_e what) +{ + switch (k1->type) { + case SSH_KEYTYPE_DSS: + if (_bignum_cmp(k1->dsa, k2->dsa, "p") != 0) { + return 1; + } + + if (_bignum_cmp(k1->dsa, k2->dsa, "q") != 0) { + return 1; + } + + if (_bignum_cmp(k1->dsa, k2->dsa, "g") != 0) { + return 1; + } + + if (_bignum_cmp(k1->dsa, k2->dsa, "y") != 0) { + return 1; + } + + if (what == SSH_KEY_CMP_PRIVATE) { + if (_bignum_cmp(k1->dsa, k2->dsa, "x") != 0) { + return 1; + } + } + break; + case SSH_KEYTYPE_RSA: + case SSH_KEYTYPE_RSA1: + if (_bignum_cmp(k1->rsa, k2->rsa, "e") != 0) { + return 1; + } + + if (_bignum_cmp(k1->rsa, k2->rsa, "n") != 0) { + return 1; + } + + if (what == SSH_KEY_CMP_PRIVATE) { + if (_bignum_cmp(k1->rsa, k2->rsa, "d") != 0) { + return 1; + } + + if (_bignum_cmp(k1->rsa, k2->rsa, "p") != 0) { + return 1; + } + + if (_bignum_cmp(k1->rsa, k2->rsa, "q") != 0) { + return 1; + } + + if (_bignum_cmp(k1->rsa, k2->rsa, "u") != 0) { + return 1; + } + } + break; + case SSH_KEYTYPE_ECDSA: + case SSH_KEYTYPE_UNKNOWN: + return 1; + } + + return 0; +} + ssh_string pki_publickey_to_blob(const ssh_key key) { ssh_buffer buffer; |