pluto and scepclient use private and public key plugins of libstrongswan

This commit is contained in:
Andreas Steffen
2009-06-09 11:03:32 +02:00
committed by Martin Willi
parent b00fbdb55a
commit 8b799d55ce
46 changed files with 1803 additions and 2597 deletions
+2 -1
View File
@@ -41,8 +41,9 @@ credentials/certificates/ac.h \
credentials/certificates/crl.h credentials/certificates/crl.c \
credentials/certificates/ocsp_request.h \
credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
database/database.h database/database_factory.h database/database_factory.c \
fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
pgp/pgp.c pgp/pgp.h \
utils.h utils.c \
utils/host.c utils/host.h \
utils/identification.c utils/identification.h \
+37 -2
View File
@@ -255,7 +255,7 @@ chunk_t asn1_build_known_oid(int n)
/*
* Defined in header.
*/
u_int asn1_length(chunk_t *blob)
size_t asn1_length(chunk_t *blob)
{
u_char n;
size_t len;
@@ -675,7 +675,7 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
}
/**
* Build an ASN.1 BITSTRING object
* Build an ASN.1 BIT_STRING object
*/
chunk_t asn1_bitstring(const char *mode, chunk_t content)
{
@@ -691,6 +691,41 @@ chunk_t asn1_bitstring(const char *mode, chunk_t content)
return object;
}
/**
* Build an ASN.1 INTEGER object
*/
chunk_t asn1_integer(const char *mode, chunk_t content)
{
chunk_t object;
size_t len;
u_char *pos;
if (content.len == 0 || (content.len == 1 && *content.ptr == 0x00))
{
/* a zero ASN.1 integer does not have a value field */
len = 0;
}
else
{
/* ASN.1 integers must be positive numbers in two's complement */
len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
}
pos = asn1_build_object(&object, ASN1_INTEGER, len);
if (len > content.len)
{
*pos++ = 0x00;
}
if (len)
{
memcpy(pos, content.ptr, content.len);
}
if (*mode == 'm')
{
free(content.ptr);
}
return object;
}
/**
* Build an ASN.1 object from a variable number of individual chunks.
* Depending on the mode, chunks either are moved ('m') or copied ('c').
+10 -1
View File
@@ -120,7 +120,7 @@ chunk_t asn1_build_known_oid(int n);
* @param blob pointer to an ASN.1 coded blob
* @return length of ASN.1 object
*/
u_int asn1_length(chunk_t *blob);
size_t asn1_length(chunk_t *blob);
/**
* Parses an ASN.1 algorithmIdentifier object
@@ -227,6 +227,15 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
*/
chunk_t asn1_bitstring(const char *mode, chunk_t content);
/**
* Build an ASN.1 INTEGER object
*
* @param mode 'c' for copy or 'm' for move
* @param content content of the INTEGER
* @return chunk containing the ASN.1 coded INTEGER
*/
chunk_t asn1_integer(const char *mode, chunk_t content);
/**
* Build an ASN.1 object from a variable number of individual chunks
*
+2
View File
@@ -20,6 +20,8 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_AGENT_SOCKET",
"BUILD_BLOB_ASN1_DER",
"BUILD_BLOB_ASN1_PEM",
"BUILD_BLOB_PGP",
"BUILD_BLOB_RFC_3110",
"BUILD_KEY_SIZE",
"BUILD_SIGNING_KEY",
"BUILD_SIGNING_CERT",
+7 -3
View File
@@ -38,14 +38,18 @@ typedef builder_t* (*builder_constructor_t)(int subtype);
* Parts to build credentials from.
*/
enum builder_part_t {
/** path to a file containing an ASN1 blob, char* */
/** path to a file containing an ASN.1 blob, char* */
BUILD_FROM_FILE,
/** unix socket of a ssh/pgp agent, char* */
BUILD_AGENT_SOCKET,
/** DER encoded ASN1 blob, chunk_t */
/** DER encoded ASN.1 blob, chunk_t */
BUILD_BLOB_ASN1_DER,
/** PEM encoded ASN1 blob, null terminated char* */
/** PEM encoded ASN.1 blob, null terminated char* */
BUILD_BLOB_ASN1_PEM,
/** OpenPGP key blob, chunk_t */
BUILD_BLOB_PGP,
/** RFC 3110 DNS public key blob, chunk_t */
BUILD_BLOB_RFC_3110,
/** key size in bits, as used for key generation, u_int */
BUILD_KEY_SIZE,
/** private key to use for signing, private_key_t* */
@@ -156,6 +156,8 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
case BUILD_END:
break;
case BUILD_BLOB_ASN1_DER:
case BUILD_BLOB_PGP:
case BUILD_BLOB_RFC_3110:
case BUILD_SERIAL:
builder->add(builder, part, va_arg(args, chunk_t));
continue;
@@ -79,6 +79,14 @@ struct private_key_t {
*/
public_key_t* (*get_public_key)(private_key_t *this);
/**
* Check if two private keys are equal.
*
* @param other other private key
* @return TRUE, if equality
*/
bool (*equals) (private_key_t *this, private_key_t *other);
/**
* Check if a private key belongs to a public key.
*
@@ -15,13 +15,15 @@
#include "public_key.h"
ENUM(key_type_names, KEY_RSA, KEY_ECDSA,
ENUM(key_type_names, KEY_RSA, KEY_DSA,
"RSA",
"ECDSA"
"ECDSA",
"DSA"
);
ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521,
"DEFAULT",
"RSA_EMSA_PKCS1_NULL",
"RSA_EMSA_PKCS1_MD5",
"RSA_EMSA_PKCS1_SHA1",
"RSA_EMSA_PKCS1_SHA256",
+33 -19
View File
@@ -34,12 +34,14 @@ typedef enum signature_scheme_t signature_scheme_t;
*/
enum key_type_t {
/** key type wildcard */
KEY_ANY,
KEY_ANY = 0,
/** RSA crypto system as in PKCS#1 */
KEY_RSA,
KEY_RSA = 1,
/** ECDSA as in ANSI X9.62 */
KEY_ECDSA,
/** DSS, ElGamal, ... */
KEY_ECDSA = 2,
/** DSA */
KEY_DSA = 3,
/** ElGamal, ... */
};
/**
@@ -50,29 +52,33 @@ extern enum_name_t *key_type_names;
/**
* Signature scheme for signature creation
*
* EMSA-PKCS1 signatures are from the PKCS#1 standard. They include
* the ASN1-OID of the used hash algorithm.
* EMSA-PKCS1 signatures are defined in PKCS#1 standard.
* A prepended ASN.1 encoded digestInfo field contains the
* OID of the used hash algorithm. The ASN.1 type of the PKCS#7
* variants is OCTET_STRING instead of the default BIT_STRING.
*/
enum signature_scheme_t {
/** default scheme of that underlying crypto system */
/** Default scheme of the underlying crypto system */
SIGN_DEFAULT,
/** EMSA-PKCS1 with MD5 */
/** EMSA-PKCS1_v1.5 signature over digest without digestInfo */
SIGN_RSA_EMSA_PKCS1_NULL,
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and MD5 */
SIGN_RSA_EMSA_PKCS1_MD5,
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash. */
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-1 */
SIGN_RSA_EMSA_PKCS1_SHA1,
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-256 */
SIGN_RSA_EMSA_PKCS1_SHA256,
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-384 */
SIGN_RSA_EMSA_PKCS1_SHA384,
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */
/** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-512 */
SIGN_RSA_EMSA_PKCS1_SHA512,
/** ECDSA using SHA-1 as hash. */
/** ECDSA with SHA-1 */
SIGN_ECDSA_WITH_SHA1,
/** ECDSA with SHA-256 on the P-256 curve as in RFC 4754 */
/** ECDSA on the P-256 curve with SHA-256 as in RFC 4754 */
SIGN_ECDSA_256,
/** ECDSA with SHA-384 on the P-384 curve as in RFC 4754 */
/** ECDSA on the P-384 curve with SHA-384 as in RFC 4754 */
SIGN_ECDSA_384,
/** ECDSA with SHA-512 on the P-521 curve as in RFC 4754 */
/** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */
SIGN_ECDSA_521,
};
@@ -107,12 +113,20 @@ struct public_key_t {
/**
* Encrypt a chunk of data.
*
* @param crypto chunk containing plaintext data
* @param plain where to allocate encrypted data
* @param plain chunk containing plaintext data
* @param crypto where to allocate encrypted data
* @return TRUE if data successfully encrypted
*/
bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain);
bool (*encrypt)(public_key_t *this, chunk_t plain, chunk_t *crypto);
/**
* Check if two public keys are equal.
*
* @param other other public key
* @return TRUE, if equality
*/
bool (*equals)(public_key_t *this, public_key_t *other);
/**
* Get the strength of the key in bytes.
*
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2002-2009 Andreas Steffen
*
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "pgp.h"
ENUM(pgp_sym_alg_names, PGP_SYM_ALG_PLAIN, PGP_SYM_ALG_TWOFISH,
"PLAINTEXT",
"IDEA",
"3DES",
"CAST5",
"BLOWFISH",
"SAFER",
"DES",
"AES_128",
"AES_192",
"AES_256",
"TWOFISH"
);
/*
* Defined in header.
*/
size_t pgp_length(chunk_t *blob, size_t len)
{
size_t size = 0;
if (len > blob->len)
{
return PGP_INVALID_LENGTH;
}
blob->len -= len;
while (len-- > 0)
{
size = 256*size + *blob->ptr++;
}
return size;
}
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2002-2009 Andreas Steffen
*
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup pgpi pgp
* @{ @ingroup pgp
*/
#ifndef PGP_H_
#define PGP_H_
typedef enum pgp_sym_alg_t pgp_sym_alg_t;
#include <chunk.h>
#include <enum.h>
/**
* OpenPGP symmetric key algorithms defined in section 9.2 of RFC 4880
*/
enum pgp_sym_alg_t {
PGP_SYM_ALG_PLAIN = 0,
PGP_SYM_ALG_IDEA = 1,
PGP_SYM_ALG_3DES = 2,
PGP_SYM_ALG_CAST5 = 3,
PGP_SYM_ALG_BLOWFISH = 4,
PGP_SYM_ALG_SAFER = 5,
PGP_SYM_ALG_DES = 6,
PGP_SYM_ALG_AES_128 = 7,
PGP_SYM_ALG_AES_192 = 8,
PGP_SYM_ALG_AES_256 = 9,
PGP_SYM_ALG_TWOFISH = 10
};
/**
* Enum names for pgp_sym_alg_t
*/
extern enum_name_t *pgp_sym_alg_names;
#define PGP_INVALID_LENGTH 0xffffffff
/**
* Returns the length of an OpenPGP (RFC 4880) packet
* The blob pointer is advanced past the length field
*
* @param blob pointer to an OpenPGP blob
* @param len size of the length field
* @return length of the next OpenPGP packet
*/
size_t pgp_length(chunk_t *blob, size_t len);
#endif /** PGP_H_ @}*/
@@ -26,6 +26,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <pgp/pgp.h>
/**
* Public exponent to use for key generation.
@@ -110,11 +111,12 @@ struct private_gmp_rsa_private_key_t {
};
/**
* shared functions, implemented in gmp_rsa_public_key.c
* Shared functions defined in gmp_rsa_public_key.c
*/
bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
identification_t **keyid_info);
gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
extern bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e,
identification_t **keyid,
identification_t **keyid_info);
extern gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
/**
* Auxiliary function overwriting private key material with zero bytes
@@ -215,32 +217,36 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
hash_algorithm_t hash_algorithm,
chunk_t data, chunk_t *signature)
{
hasher_t *hasher;
chunk_t em, digestInfo, hash;
int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
if (hash_oid == OID_UNKNOWN)
{
return FALSE;
}
chunk_t digestInfo = chunk_empty;
chunk_t em;
/* get hasher */
hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
if (hasher == NULL)
if (hash_algorithm != HASH_UNKNOWN)
{
return FALSE;
hasher_t *hasher;
chunk_t hash;
int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
if (hash_oid == OID_UNKNOWN)
{
return FALSE;
}
hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
if (hasher == NULL)
{
return FALSE;
}
hasher->allocate_hash(hasher, data, &hash);
hasher->destroy(hasher);
/* build DER-encoded digestInfo */
digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
asn1_algorithmIdentifier(hash_oid),
asn1_simple_object(ASN1_OCTET_STRING, hash)
);
chunk_free(&hash);
data = digestInfo;
}
/* build hash */
hasher->allocate_hash(hasher, data, &hash);
hasher->destroy(hasher);
/* build DER-encoded digestInfo */
digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
asn1_algorithmIdentifier(hash_oid),
asn1_simple_object(ASN1_OCTET_STRING, hash)
);
chunk_free(&hash);
/* build chunk to rsa-decrypt:
* EM = 0x00 || 0x01 || PS || 0x00 || T.
@@ -255,9 +261,9 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
/* set magic bytes */
*(em.ptr) = 0x00;
*(em.ptr+1) = 0x01;
*(em.ptr + em.len - digestInfo.len - 1) = 0x00;
*(em.ptr + em.len - data.len - 1) = 0x00;
/* set DER-encoded hash */
memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
/* build signature */
*signature = rsasp1(this, em);
@@ -269,7 +275,7 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.get_type.
*/
static key_type_t get_type(private_gmp_rsa_private_key_t *this)
{
@@ -277,15 +283,16 @@ static key_type_t get_type(private_gmp_rsa_private_key_t *this)
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.sign.
*/
static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
{
switch (scheme)
{
case SIGN_RSA_EMSA_PKCS1_NULL:
return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
case SIGN_DEFAULT:
/* default is EMSA-PKCS1 using SHA1 */
case SIGN_RSA_EMSA_PKCS1_SHA1:
return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -304,7 +311,7 @@ static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.decrypt.
*/
static bool decrypt(private_gmp_rsa_private_key_t *this,
chunk_t crypto, chunk_t *plain)
@@ -314,7 +321,7 @@ static bool decrypt(private_gmp_rsa_private_key_t *this,
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.get_keysize.
*/
static size_t get_keysize(private_gmp_rsa_private_key_t *this)
{
@@ -322,7 +329,7 @@ static size_t get_keysize(private_gmp_rsa_private_key_t *this)
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.get_id.
*/
static identification_t* get_id(private_gmp_rsa_private_key_t *this,
id_type_t type)
@@ -347,7 +354,35 @@ static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.equals.
*/
static bool equals(private_gmp_rsa_private_key_t *this, private_key_t *other)
{
identification_t *keyid;
if (&this->public.interface == other)
{
return TRUE;
}
if (other->get_type(other) != KEY_RSA)
{
return FALSE;
}
keyid = other->get_id(other, ID_PUBKEY_SHA1);
if (keyid && keyid->equals(keyid, this->keyid))
{
return TRUE;
}
keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
if (keyid && keyid->equals(keyid, this->keyid_info))
{
return TRUE;
}
return FALSE;
}
/**
* Implementation of gmp_rsa_private_key.belongs_to.
*/
static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public)
{
@@ -371,19 +406,27 @@ static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public
}
/**
* convert a MP integer into a DER coded ASN.1 object
* Convert a MP integer into a chunk_t
*/
chunk_t gmp_mpz_to_asn1(const mpz_t value)
chunk_t gmp_mpz_to_chunk(const mpz_t value)
{
chunk_t n;
n.len = 1 + mpz_sizeinbase(value, 2) / 8; /* size in bytes */
n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE;
n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
if (n.ptr == NULL)
{ /* if we have zero in "value", gmp returns NULL */
n.len = 0;
}
return asn1_wrap(ASN1_INTEGER, "m", n);
return n;
}
/**
* Convert a MP integer into a DER coded ASN.1 object
*/
chunk_t gmp_mpz_to_asn1(const mpz_t value)
{
return asn1_wrap(ASN1_INTEGER, "m", gmp_mpz_to_chunk(value));
}
/**
@@ -404,7 +447,7 @@ static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
}
/**
* Implementation of gmp_rsa_private_key.destroy.
* Implementation of gmp_rsa_private_key.get_ref.
*/
static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
{
@@ -445,14 +488,14 @@ static status_t check(private_gmp_rsa_private_key_t *this)
/* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
* We actually require more (for security).
*/
if (this->k < 512/8)
if (this->k < 512 / BITS_PER_BYTE)
{
DBG1("key shorter than 512 bits");
return FAILED;
}
/* we picked a max modulus size to simplify buffer allocation */
if (this->k > 8192/8)
if (this->k > 8192 / BITS_PER_BYTE)
{
DBG1("key larger than 8192 bits");
return FAILED;
@@ -540,16 +583,17 @@ static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
{
private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_rsa_private_key_t);
this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type;
this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign;
this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize;
this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to;
this->public.interface.get_encoding = (chunk_t (*) (private_key_t*))get_encoding;
this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref;
this->public.interface.destroy = (void (*) (private_key_t*))destroy;
this->keyid = NULL;
this->keyid_info = NULL;
@@ -567,7 +611,7 @@ static gmp_rsa_private_key_t *generate(size_t key_size)
mpz_t m, q1, t;
private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
key_size = key_size / 8;
key_size = key_size / BITS_PER_BYTE;
/* Get values of primes p and q */
if (compute_prime(this, key_size/2, &p) != SUCCESS)
@@ -678,7 +722,7 @@ static const asn1Object_t privkeyObjects[] = {
/**
* load private key from a ASN1 encoded blob
*/
static gmp_rsa_private_key_t *load(chunk_t blob)
static gmp_rsa_private_key_t *load_asn1_der(chunk_t blob)
{
asn1_parser_t *parser;
chunk_t object;
@@ -706,6 +750,7 @@ static gmp_rsa_private_key_t *load(chunk_t blob)
case PRIV_KEY_VERSION:
if (object.len > 0 && *object.ptr != 0)
{
DBG1("PKCS#1 private key format is not version 1");
goto end;
}
break;
@@ -755,7 +800,6 @@ end:
destroy(this);
return NULL;
}
if (check(this) != SUCCESS)
{
destroy(this);
@@ -764,6 +808,125 @@ end:
return &this->public;
}
/**
* load private key from an OpenPGP blob coded according to section
*/
static gmp_rsa_private_key_t *load_pgp(chunk_t blob)
{
mpz_t u;
int objectID;
pgp_sym_alg_t s2k;
chunk_t packet = blob;
private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
mpz_init(this->n);
mpz_init(this->e);
mpz_init(this->p);
mpz_init(this->q);
mpz_init(this->d);
mpz_init(this->exp1);
mpz_init(this->exp2);
mpz_init(this->coeff);
/* string-to-key usage */
s2k = pgp_length(&packet, 1);
DBG2("L3 - string-to-key: %d", s2k);
if (s2k == 255 || s2k == 254)
{
DBG1("string-to-key specifiers not supported");
goto end;
}
DBG2(" %N", pgp_sym_alg_names, s2k);
if (s2k != PGP_SYM_ALG_PLAIN)
{
DBG1("%N encryption not supported", pgp_sym_alg_names, s2k);
goto end;
}
for (objectID = PRIV_KEY_MODULUS; objectID <= PRIV_KEY_PRIME2; objectID++)
{
chunk_t object;
object.len = pgp_length(&packet, 2);
if (object.len == PGP_INVALID_LENGTH)
{
DBG1("OpenPGP length is invalid");
goto end;
}
object.len = (object.len + 7) / BITS_PER_BYTE;
if (object.len > packet.len)
{
DBG1("OpenPGP field is too short");
goto end;
}
object.ptr = packet.ptr;
packet.ptr += object.len;
packet.len -= object.len;
switch (objectID)
{
case PRIV_KEY_MODULUS:
mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
break;
case PRIV_KEY_PUB_EXP:
mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
break;
case PRIV_KEY_PRIV_EXP:
mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
break;
case PRIV_KEY_PRIME1:
mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
break;
case PRIV_KEY_PRIME2:
mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
break;
}
}
/* auxiliary variable */
mpz_init(u);
/* exp1 = d mod (p-1) */
mpz_sub_ui(u, this->p, 1);
mpz_mod(this->exp1, this->d, u);
/* exp2 = d mod (q-1) */
mpz_sub_ui(u, this->q, 1);
mpz_mod(this->exp2, this->d, u);
/* coeff = (q^-1) mod p */
mpz_invert(this->coeff, this->q, this->p);
if (mpz_cmp_ui(this->coeff, 0) < 0)
{
mpz_add(this->coeff, this->coeff, this->p);
}
mpz_clear(u);
chunk_clear(&blob);
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
{
destroy(this);
return NULL;
}
if (check(this) != SUCCESS)
{
destroy(this);
return NULL;
}
return &this->public;
end:
chunk_clear(&blob);
destroy(this);
return NULL;
}
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for key loading/generation
@@ -802,7 +965,15 @@ static void add(private_builder_t *this, builder_part_t part, ...)
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
this->key = load(chunk_clone(chunk));
this->key = load_asn1_der(chunk_clone(chunk));
va_end(args);
return;
}
case BUILD_BLOB_PGP:
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
this->key = load_pgp(chunk_clone(chunk));
va_end(args);
return;
}
@@ -28,11 +28,7 @@
#include <asn1/asn1_parser.h>
#include <asn1/pem.h>
#include <crypto/hashers/hasher.h>
/**
* defined in gmp_rsa_private_key.c
*/
extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
#include <pgp/pgp.h>
typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t;
@@ -76,6 +72,12 @@ struct private_gmp_rsa_public_key_t {
refcount_t ref;
};
/**
* Shared functions defined in gmp_rsa_private_key.c
*/
extern chunk_t gmp_mpz_to_chunk(const mpz_t value);
extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
/**
* RSAEP algorithm specified in PKCS#1.
*/
@@ -189,13 +191,24 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
goto end;
}
/* parse ASN.1-based digestInfo */
{
if (algorithm == HASH_UNKNOWN)
{ /* IKEv1 signatures without digestInfo */
if (em.len != data.len)
{
DBG1("hash size in signature is %u bytes instead of %u bytes",
em.len, data.len);
goto end;
}
success = memeq(em.ptr, data.ptr, data.len);
}
else
{ /* IKEv2 and X.509 certificate signatures */
asn1_parser_t *parser;
chunk_t object;
int objectID;
hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
DBG2("signature verification:");
parser = asn1_parser_create(digestInfoObjects, em);
while (parser->iterate(parser, &objectID, &object))
@@ -218,8 +231,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
parser->get_level(parser)+1, NULL);
hash_algorithm = hasher_algorithm_from_oid(hash_oid);
if (hash_algorithm == HASH_UNKNOWN ||
(algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
if (hash_algorithm == HASH_UNKNOWN || hash_algorithm != algorithm)
{
DBG1("expected hash algorithm %N, but found %N (OID: %#B)",
hash_algorithm_names, algorithm,
@@ -287,7 +299,8 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme
{
switch (scheme)
{
case SIGN_DEFAULT: /* default is EMSA-PKCS1 using included OID */
case SIGN_DEFAULT:
case SIGN_RSA_EMSA_PKCS1_NULL:
return verify_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
@@ -315,6 +328,34 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t crypto, chunk_t
return FALSE;
}
/**
* Implementation of gmp_rsa_public_key.equals.
*/
static bool equals(private_gmp_rsa_public_key_t *this, public_key_t *other)
{
identification_t *keyid;
if (&this->public.interface == other)
{
return TRUE;
}
if (other->get_type(other) != KEY_RSA)
{
return FALSE;
}
keyid = other->get_id(other, ID_PUBKEY_SHA1);
if (keyid && keyid->equals(keyid, this->keyid))
{
return TRUE;
}
keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
if (keyid && keyid->equals(keyid, this->keyid_info))
{
return TRUE;
}
return FALSE;
}
/**
* Implementation of public_key_t.get_keysize.
*/
@@ -323,6 +364,34 @@ static size_t get_keysize(private_gmp_rsa_public_key_t *this)
return this->k;
}
/**
* Build the PGP version 3 RSA key identifier from n and e using
* MD5 hashed modulus and exponent. Also used in rsa_private_key.c.
*/
static identification_t* gmp_rsa_build_pgp_v3_keyid(mpz_t n, mpz_t e)
{
identification_t *keyid;
chunk_t modulus, exponent, hash;
hasher_t *hasher;
hasher= lib->crypto->create_hasher(lib->crypto, HASH_MD5);
if (hasher == NULL)
{
DBG1("computation of PGP V3 key ID failed, no MD5 hasher is available");
return NULL;
}
modulus = gmp_mpz_to_chunk(n);
exponent = gmp_mpz_to_chunk(e);
hasher->allocate_hash(hasher, modulus, NULL);
hasher->allocate_hash(hasher, exponent, &hash);
hasher->destroy(hasher);
keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
free(hash.ptr);
free(modulus.ptr);
free(exponent.ptr);
return keyid;
}
/**
* Implementation of public_key_t.get_id.
*/
@@ -335,6 +404,8 @@ static identification_t *get_id(private_gmp_rsa_public_key_t *this,
return this->keyid_info;
case ID_PUBKEY_SHA1:
return this->keyid;
case ID_KEY_ID:
return gmp_rsa_build_pgp_v3_keyid(this->n, this->e);
default:
return NULL;
}
@@ -381,14 +452,15 @@ static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty()
{
private_gmp_rsa_public_key_t *this = malloc_thing(private_gmp_rsa_public_key_t);
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
this->public.interface.get_type = (key_type_t (*) (public_key_t*))get_type;
this->public.interface.verify = (bool (*) (public_key_t*, signature_scheme_t, chunk_t, chunk_t))verify;
this->public.interface.encrypt = (bool (*) (public_key_t*, chunk_t, chunk_t*))encrypt_;
this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
this->public.interface.get_keysize = (size_t (*) (public_key_t*))get_keysize;
this->public.interface.get_id = (identification_t* (*) (public_key_t*, id_type_t))get_id;
this->public.interface.get_encoding = (chunk_t(*) (public_key_t*))get_encoding;
this->public.interface.get_ref = (public_key_t* (*) (public_key_t *this))get_ref;
this->public.interface.destroy = (void (*) (public_key_t *this))destroy;
this->keyid = NULL;
this->keyid_info = NULL;
@@ -443,7 +515,7 @@ gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e)
mpz_init_set(this->n, n);
mpz_init_set(this->e, e);
this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
{
@@ -467,9 +539,9 @@ static const asn1Object_t pubkeyObjects[] = {
#define PUB_KEY_EXPONENT 2
/**
* Load a public key from an ASN1 encoded blob
* Load a public key from an ASN.1 encoded blob
*/
static gmp_rsa_public_key_t *load(chunk_t blob)
static gmp_rsa_public_key_t *load_asn1_der(chunk_t blob)
{
asn1_parser_t *parser;
chunk_t object;
@@ -505,7 +577,7 @@ static gmp_rsa_public_key_t *load(chunk_t blob)
return NULL;
}
this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
@@ -516,6 +588,125 @@ static gmp_rsa_public_key_t *load(chunk_t blob)
return &this->public;
}
/**
* Load a public key from an OpenPGP blob
*/
static gmp_rsa_public_key_t* load_pgp(chunk_t blob)
{
chunk_t exponent, modulus;
chunk_t packet = blob;
private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
mpz_init(this->n);
mpz_init(this->e);
/* modulus n */
modulus.len = (pgp_length(&packet, 2) + 7) / BITS_PER_BYTE;
modulus.ptr = packet.ptr;
if (modulus.len > packet.len)
{
DBG1("OpenPGP public key blob too short for modulus");
goto end;
}
packet.ptr += modulus.len;
packet.len -= modulus.len;
DBG2("L3 - modulus:");
DBG3("%B", &modulus);
/* public exponent e */
exponent.len = (pgp_length(&packet, 2) + 7) / BITS_PER_BYTE;
exponent.ptr = packet.ptr;
if (exponent.len > packet.len)
{
DBG1("OpenPGP public key blob too short for exponent");
goto end;
}
DBG2("L3 - public exponent:");
DBG3("%B", &exponent);
mpz_import(this->n, modulus.len, 1, 1, 1, 0, modulus.ptr);
mpz_import(this->e, exponent.len, 1, 1, 1, 0, exponent.ptr);
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
free(blob.ptr);
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
{
destroy(this);
return NULL;
}
return &this->public;
end:
free(blob.ptr);
destroy(this);
return NULL;
}
/**
* Load a public key from an RFC 3110 encoded blob
*/
static gmp_rsa_public_key_t *load_rfc_3110(chunk_t blob)
{
chunk_t exponent, modulus;
u_char *pos = blob.ptr;
size_t len = blob.len;
private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
mpz_init(this->n);
mpz_init(this->e);
if (blob.len < 3)
{
DBG1("RFC 3110 public key blob too short for exponent length");
goto end;
}
if (pos[0] != 0x00)
{
exponent = chunk_create(pos + 1, pos[0]);
pos++;
len--;
}
else
{
exponent = chunk_create(pos + 3, 256*pos[1] + pos[2]);
pos += 3;
len -= 3;
}
if (exponent.len > len)
{
DBG1("RFC 3110 public key blob too short for exponent");
goto end;
}
pos += exponent.len;
len -= exponent.len;
if (len == 0)
{
DBG1("RFC 3110 public key blob has zero length modulus");
goto end;
}
modulus = chunk_create(pos, len);
mpz_import(this->n, modulus.len, 1, 1, 1, 0, modulus.ptr);
mpz_import(this->e, exponent.len, 1, 1, 1, 0, exponent.ptr);
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
free(blob.ptr);
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
{
destroy(this);
return NULL;
}
return &this->public;
end:
free(blob.ptr);
destroy(this);
return NULL;
}
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for key loading
@@ -554,7 +745,23 @@ static void add(private_builder_t *this, builder_part_t part, ...)
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
this->key = load(chunk_clone(chunk));
this->key = load_asn1_der(chunk_clone(chunk));
va_end(args);
return;
}
case BUILD_BLOB_PGP:
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
this->key = load_pgp(chunk_clone(chunk));
va_end(args);
return;
}
case BUILD_BLOB_RFC_3110:
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
this->key = load_rfc_3110(chunk_clone(chunk));
va_end(args);
return;
}
@@ -136,7 +136,7 @@ error:
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.get_type.
*/
static key_type_t get_type(private_openssl_rsa_private_key_t *this)
{
@@ -144,7 +144,7 @@ static key_type_t get_type(private_openssl_rsa_private_key_t *this)
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.sign.
*/
static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
@@ -152,7 +152,6 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
switch (scheme)
{
case SIGN_DEFAULT:
/* default is EMSA-PKCS1 using SHA1 */
case SIGN_RSA_EMSA_PKCS1_SHA1:
return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -171,7 +170,7 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.decrypt.
*/
static bool decrypt(private_openssl_rsa_private_key_t *this,
chunk_t crypto, chunk_t *plain)
@@ -181,7 +180,7 @@ static bool decrypt(private_openssl_rsa_private_key_t *this,
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.get_keysize.
*/
static size_t get_keysize(private_openssl_rsa_private_key_t *this)
{
@@ -189,7 +188,7 @@ static size_t get_keysize(private_openssl_rsa_private_key_t *this)
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.get_id.
*/
static identification_t* get_id(private_openssl_rsa_private_key_t *this,
id_type_t type)
@@ -206,7 +205,7 @@ static identification_t* get_id(private_openssl_rsa_private_key_t *this,
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.get_public_key.
*/
static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
{
@@ -214,7 +213,35 @@ static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.equals.
*/
static bool equals(private_openssl_rsa_private_key_t *this, private_key_t *other)
{
identification_t *keyid;
if (&this->public.interface == other)
{
return TRUE;
}
if (other->get_type(other) != KEY_RSA)
{
return FALSE;
}
keyid = other->get_id(other, ID_PUBKEY_SHA1);
if (keyid && keyid->equals(keyid, this->keyid))
{
return TRUE;
}
keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
if (keyid && keyid->equals(keyid, this->keyid_info))
{
return TRUE;
}
return FALSE;
}
/**
* Implementation of openssl_rsa_private_key.belongs_to.
*/
static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
{
@@ -253,7 +280,7 @@ static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
}
/**
* Implementation of openssl_rsa_private_key.destroy.
* Implementation of openssl_rsa_private_key.get_ref.
*/
static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
{
@@ -286,16 +313,17 @@ static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(v
{
private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type;
this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign;
this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize;
this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to;
this->public.interface.get_encoding = (chunk_t(*) (private_key_t*))get_encoding;
this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref;
this->public.interface.destroy = (void (*) (private_key_t*))destroy;
this->engine = FALSE;
this->keyid = NULL;
@@ -124,7 +124,6 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
switch (scheme)
{
case SIGN_DEFAULT:
/* default is EMSA-PKCS1 using SHA1 */
case SIGN_RSA_EMSA_PKCS1_SHA1:
return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -151,6 +150,34 @@ static bool encrypt_(private_openssl_rsa_public_key_t *this, chunk_t crypto, chu
return FALSE;
}
/**
* Implementation of public_key_t.equals.
*/
static bool equals(private_openssl_rsa_public_key_t *this, public_key_t *other)
{
identification_t *keyid;
if (&this->public.interface == other)
{
return TRUE;
}
if (other->get_type(other) != KEY_RSA)
{
return FALSE;
}
keyid = other->get_id(other, ID_PUBKEY_SHA1);
if (keyid && keyid->equals(keyid, this->keyid))
{
return TRUE;
}
keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
if (keyid && keyid->equals(keyid, this->keyid_info))
{
return TRUE;
}
return FALSE;
}
/**
* Implementation of public_key_t.get_keysize.
*/
@@ -262,6 +289,7 @@ static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty()
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+14 -15
View File
@@ -730,7 +730,6 @@ static bool parse_certificate(private_x509_cert_t *this)
KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
if (this->public_key == NULL)
{
DBG1("could not create public key");
goto end;
}
break;
@@ -1123,19 +1122,19 @@ static private_x509_cert_t* create_empty(void)
{
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
this->public.interface.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
this->public.interface.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
this->public.interface.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_issuer;
this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_issuer;
this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
this->public.interface.get_flags = (x509_flag_t (*)(x509_t*))get_flags;
this->public.interface.get_serial = (chunk_t (*)(x509_t*))get_serial;
this->public.interface.get_authKeyIdentifier = (identification_t* (*)(x509_t*))get_authKeyIdentifier;
@@ -1314,7 +1313,7 @@ static bool generate(private_builder_t *this)
this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
asn1_simple_object(ASN1_INTEGER, this->cert->serialNumber),
asn1_integer("c", this->cert->serialNumber),
asn1_algorithmIdentifier(this->cert->algorithm),
issuer->get_encoding(issuer),
asn1_wrap(ASN1_SEQUENCE, "mm",