aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-09-18 22:04:03 +0200
committerAndreas Schneider <asn@cryptomilk.org>2011-10-29 19:58:28 +0200
commit2c04994443384224161d895d00255b5788e8376d (patch)
treed07f4eb26408d4e0f8b76d96212e11f23b20f699 /src
parente799c0ce7d046606d9391d826461c2782f072fa0 (diff)
downloadlibssh-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.c34
-rw-r--r--src/pki_crypto.c58
-rw-r--r--src/pki_gcrypt.c99
3 files changed, 191 insertions, 0 deletions
diff --git a/src/pki.c b/src/pki.c
index c6f0e5f..c3ff339 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -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;