added private flag to asn1_init
[strongswan.git] / src / libstrongswan / crypto / rsa / rsa_private_key.c
index f8798bb..8dfced5 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 /*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 #include <unistd.h>
 #include <string.h>
 
+#include "rsa_public_key.h"
 #include "rsa_private_key.h"
 
-#include <daemon.h>
 #include <asn1/asn1.h>
 #include <asn1/pem.h>
+#include <utils/randomizer.h>
 
-/* 
- * Oids for hash algorithms are defined in
- * rsa_public_key.c.
+/**
+ * OIDs for hash algorithms are defined in rsa_public_key.c.
  */
 extern u_int8_t md2_oid[18];
 extern u_int8_t md5_oid[18];
@@ -44,6 +45,12 @@ extern u_int8_t sha512_oid[19];
 
 
 /**
+ * defined in rsa_public_key.c
+ */
+extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
+
+
+/**
  *  Public exponent to use for key generation.
  */
 #define PUBLIC_EXPONENT 0x10001
@@ -109,6 +116,12 @@ struct private_rsa_private_key_t {
         * Keysize in bytes.
         */
        size_t k;
+
+       /**
+        * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+        */
+       chunk_t keyid;
+
        
        /**
         * @brief Implements the RSADP algorithm specified in PKCS#1.
@@ -251,8 +264,8 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, hash
 {
        hasher_t *hasher;
        chunk_t hash;
-       chunk_t oid;
        chunk_t em;
+       chunk_t oid;
        
        /* get oid string prepended to hash */
        switch (hash_algorithm)
@@ -406,11 +419,7 @@ rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
  */
 static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
 {
-       if (mpz_cmp(this->n, *public->get_modulus(public)) == 0)
-       {
-               return TRUE;
-       }
-       return FALSE;
+       return chunk_equals(this->keyid, public->get_keyid(public));
 }
 
 /**
@@ -522,6 +531,7 @@ static rsa_private_key_t* _clone(private_rsa_private_key_t *this)
        mpz_init_set(clone->exp1, this->exp1);
        mpz_init_set(clone->exp2, this->exp2);
        mpz_init_set(clone->coeff, this->coeff);
+       clone->keyid = chunk_clone(this->keyid);
        clone->k = this->k;
        
        return &clone->public;
@@ -540,6 +550,7 @@ static void destroy(private_rsa_private_key_t *this)
        mpz_clear(this->exp1);
        mpz_clear(this->exp2);
        mpz_clear(this->coeff);
+       free(this->keyid.ptr);
        free(this);
 }
 
@@ -676,7 +687,7 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
        mpz_init(this->exp2);
        mpz_init(this->coeff);
        
-       asn1_init(&ctx, blob, 0, FALSE);
+       asn1_init(&ctx, blob, 0, FALSE, TRUE);
        
        while (objectID < PRIV_KEY_ROOF) 
        {
@@ -723,6 +734,16 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
        }
        
        this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+
+       /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
+       {
+               chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(this->n, this->e);
+               hasher_t *hasher = hasher_create(HASH_SHA1);
+
+               hasher->allocate_hash(hasher, publicKeyInfo, &this->keyid);
+               hasher->destroy(hasher);
+               free(publicKeyInfo.ptr);
+       }
        
        if (check(this) != SUCCESS)
        {
@@ -738,7 +759,7 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
 /*
  * see header
  */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
+rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase)
 {
        bool pgp = FALSE;
        chunk_t chunk = CHUNK_INITIALIZER;