diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-01-22 10:32:37 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-01-22 10:32:37 +0000 |
commit | cd543a69a271607ff3899de6bc29961461074f78 (patch) | |
tree | 7001cb21944eb98730918a4acdb7ab1b0a26a829 | |
parent | 2d49eaa1312d3fba7870be73f767c21bdd4e8294 (diff) | |
download | strongswan-cd543a69a271607ff3899de6bc29961461074f78.tar.bz2 strongswan-cd543a69a271607ff3899de6bc29961461074f78.tar.xz |
extended asn1_algorithmIdentifier() to SHA-2
-rw-r--r-- | src/libstrongswan/asn1/asn1.c | 103 | ||||
-rw-r--r-- | src/libstrongswan/asn1/asn1.h | 30 | ||||
-rw-r--r-- | src/libstrongswan/crypto/hashers/hasher.c | 36 | ||||
-rw-r--r-- | src/libstrongswan/crypto/hashers/hasher.h | 19 | ||||
-rw-r--r-- | src/libstrongswan/crypto/ocsp.c | 7 | ||||
-rw-r--r-- | src/libstrongswan/crypto/pkcs7.c | 226 | ||||
-rw-r--r-- | src/libstrongswan/crypto/pkcs7.h | 44 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_private_key.c | 57 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_private_key.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_public_key.c | 18 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_public_key.h | 4 | ||||
-rwxr-xr-x | src/libstrongswan/crypto/x509.c | 39 |
12 files changed, 444 insertions, 143 deletions
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index e2ffd8c5b..59d848b7b 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -1,6 +1,15 @@ -/* Simple ASN.1 parser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Will, Hochschule fuer Technik Rapperswil +/** + * @file asn1.c + * + * @brief Simple ASN.1 parser + * + */ + +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 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 @@ -91,6 +100,27 @@ static u_char ASN1_sha1WithRSA_id_str[] = { 0x05, 0x00 }; +static u_char ASN1_sha256WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00 +}; + +static u_char ASN1_sha384WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C, + 0x05, 0x00 +}; + +static u_char ASN1_sha512WithRSA_id_str[] = { + 0x30, 0x0D, + 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D, + 0x05, 0x00 +}; + static u_char ASN1_rsaEncryption_id_str[] = { 0x30, 0x0D, 0x06, 0x09, @@ -98,15 +128,18 @@ static u_char ASN1_rsaEncryption_id_str[] = { 0x05, 0x00 }; -const chunk_t ASN1_md2_id = chunk_from_buf(ASN1_md2_id_str); -const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str); -const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str); -const chunk_t ASN1_sha256_id = chunk_from_buf(ASN1_sha256_id_str); -const chunk_t ASN1_sha384_id = chunk_from_buf(ASN1_sha384_id_str); -const chunk_t ASN1_sha512_id = chunk_from_buf(ASN1_sha512_id_str); -const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str); -const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str); -const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str); +static const chunk_t ASN1_md2_id = chunk_from_buf(ASN1_md2_id_str); +static const chunk_t ASN1_md5_id = chunk_from_buf(ASN1_md5_id_str); +static const chunk_t ASN1_sha1_id = chunk_from_buf(ASN1_sha1_id_str); +static const chunk_t ASN1_sha256_id = chunk_from_buf(ASN1_sha256_id_str); +static const chunk_t ASN1_sha384_id = chunk_from_buf(ASN1_sha384_id_str); +static const chunk_t ASN1_sha512_id = chunk_from_buf(ASN1_sha512_id_str); +static const chunk_t ASN1_rsaEncryption_id = chunk_from_buf(ASN1_rsaEncryption_id_str); +static const chunk_t ASN1_md5WithRSA_id = chunk_from_buf(ASN1_md5WithRSA_id_str); +static const chunk_t ASN1_sha1WithRSA_id = chunk_from_buf(ASN1_sha1WithRSA_id_str); +static const chunk_t ASN1_sha256WithRSA_id = chunk_from_buf(ASN1_sha256WithRSA_id_str); +static const chunk_t ASN1_sha384WithRSA_id = chunk_from_buf(ASN1_sha384WithRSA_id_str); +static const chunk_t ASN1_sha512WithRSA_id = chunk_from_buf(ASN1_sha512WithRSA_id_str); /* ASN.1 definiton of an algorithmIdentifier */ static const asn1Object_t algorithmIdentifierObjects[] = { @@ -132,10 +165,24 @@ chunk_t asn1_algorithmIdentifier(int oid) return ASN1_md5WithRSA_id; case OID_SHA1_WITH_RSA: return ASN1_sha1WithRSA_id; + case OID_SHA256_WITH_RSA: + return ASN1_sha256WithRSA_id; + case OID_SHA384_WITH_RSA: + return ASN1_sha384WithRSA_id; + case OID_SHA512_WITH_RSA: + return ASN1_sha512WithRSA_id; + case OID_MD2: + return ASN1_md2_id; case OID_MD5: return ASN1_md5_id; case OID_SHA1: return ASN1_sha1_id; + case OID_SHA256: + return ASN1_sha256_id; + case OID_SHA384: + return ASN1_sha384_id; + case OID_SHA512: + return ASN1_sha512_id; default: return chunk_empty; } @@ -706,6 +753,23 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) } /** + * Build an ASN.1 BITSTRING object + */ +chunk_t asn1_bitstring(const char *mode, chunk_t content) +{ + chunk_t object; + u_char *pos = build_asn1_object(&object, ASN1_BIT_STRING, 1 + content.len); + + *pos++ = 0x00; + 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'). */ @@ -736,17 +800,12 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) { chunk_t ch = va_arg(chunks, chunk_t); - switch (*mode++) + memcpy(pos, ch.ptr, ch.len); + pos += ch.len; + + if (*mode++ == 'm') { - case 'm': - memcpy(pos, ch.ptr, ch.len); - pos += ch.len; - free(ch.ptr); - break; - case 'c': - default: - memcpy(pos, ch.ptr, ch.len); - pos += ch.len; + free(ch.ptr); } } va_end(chunks); diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h index ef19ea064..4eaf1a78d 100644 --- a/src/libstrongswan/asn1/asn1.h +++ b/src/libstrongswan/asn1/asn1.h @@ -1,6 +1,15 @@ -/* Simple ASN.1 parser - * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur - * Copyright (C) 2006 Martin Will, Hochschule fuer Technik Rapperswil +/** + * @file asn1.h + * + * @brief Simple ASN.1 parser + * + */ + +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 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 @@ -114,19 +123,9 @@ extern const chunk_t ASN1_INTEGER_0; extern const chunk_t ASN1_INTEGER_1; extern const chunk_t ASN1_INTEGER_2; -/* some popular algorithmIdentifiers */ -extern const chunk_t ASN1_md2_id; -extern const chunk_t ASN1_md5_id; -extern const chunk_t ASN1_sha1_id; -extern const chunk_t ASN1_sha256_id; -extern const chunk_t ASN1_sha384_id; -extern const chunk_t ASN1_sha512_id; - -extern const chunk_t ASN1_rsaEncryption_id; -extern const chunk_t ASN1_md5WithRSA_id; -extern const chunk_t ASN1_sha1WithRSA_id; - +/* returns some popular algorithmIdentifiers */ extern chunk_t asn1_algorithmIdentifier(int oid); + extern int known_oid(chunk_t object); extern u_int asn1_length(chunk_t *blob); extern bool is_printablestring(chunk_t str); @@ -144,6 +143,7 @@ extern void code_asn1_length(size_t length, chunk_t *code); extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen); extern chunk_t asn1_integer_from_mpz(const mpz_t value); extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content); +extern chunk_t asn1_bitstring(const char *mode, chunk_t content); extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...); #endif /* _ASN1_H */ diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index fa91ec245..d8c6ff94c 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -6,8 +6,9 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -110,6 +111,39 @@ hash_algorithm_t hasher_algorithm_from_oid(int oid) /* * Described in header. */ +int hasher_algorithm_to_oid(hash_algorithm_t alg) +{ + int oid; + + switch (alg) + { + case HASH_MD2: + oid = OID_MD2; + break; + case HASH_MD5: + oid = OID_MD5; + break; + case HASH_SHA1: + oid = OID_SHA1; + break; + case HASH_SHA256: + oid = OID_SHA256; + break; + case HASH_SHA384: + oid = OID_SHA384; + break; + case HASH_SHA512: + oid = OID_SHA512; + break; + default: + oid = OID_UNKNOWN; + } + return oid; +} + +/* + * Described in header. + */ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg) { int oid; diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index 65c31a0a1..d6604b883 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -6,8 +6,9 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -171,11 +172,23 @@ hasher_t *hasher_create(hash_algorithm_t hash_algorithm); hash_algorithm_t hasher_algorithm_from_oid(int oid); /** - * @brief Conversion of hash signature algorithm ASN.1 OID. + * @brief Conversion of hash algorithm into ASN.1 OID. + * + * @param alg hash algorithm + * @return + * - ASN.1 hash OID if known hash algorithm + * - OID_UNKNOW + * + * @ingroup hashers + */ +int hasher_algorithm_to_oid(hash_algorithm_t alg); + +/** + * @brief Conversion of hash signature algorithm into ASN.1 OID. * * @param alg hash algorithm * @return - * - ASN.1 OID if known hash algorithm + * - ASN.1 signature OID if known hash algorithm * - OID_UNKNOW * * @ingroup hashers diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c index e4d907188..627a8aa4e 100644 --- a/src/libstrongswan/crypto/ocsp.c +++ b/src/libstrongswan/crypto/ocsp.c @@ -6,8 +6,11 @@ */ /* Support of the Online Certificate Status Protocol (OCSP) + * * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen - * Zuercher Hochschule Winterthur + * Copyright (C) 2007 Andreas Steffen + * + * Hochschule für 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 @@ -325,7 +328,7 @@ static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo) chunk_t serialNumber = certinfo->get_serialNumber(certinfo); chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm", - ASN1_sha1_id, + asn1_algorithmIdentifier(OID_SHA1), asn1_simple_object(ASN1_OCTET_STRING, this->authNameID), asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID), asn1_simple_object(ASN1_INTEGER, serialNumber)); diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c index 6ccb0ef56..820cbd543 100644 --- a/src/libstrongswan/crypto/pkcs7.c +++ b/src/libstrongswan/crypto/pkcs7.c @@ -7,7 +7,7 @@ /* * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2005 Andreas Steffen + * Copyright (C) 2002-2008 Andreas Steffen * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ #include <crypto/x509.h> #include <crypto/hashers/hasher.h> #include <crypto/crypters/crypter.h> +#include <crypto/rsa/rsa_public_key.h> +#include <utils/randomizer.h> #include <utils/linked_list.h> #include "pkcs7.h" @@ -262,7 +264,7 @@ static const chunk_t ASN1_messageDigest_oid = chunk_from_buf(ASN1_messageDigest_oid_str); /** - * Implements pkcs7_t.is_signedData. + * Implements pkcs7_t.is_data. */ static bool is_data(private_pkcs7_t *this) { @@ -278,7 +280,7 @@ static bool is_signedData(private_pkcs7_t *this) } /** - * Implements pkcs7_t.is_signedData. + * Implements pkcs7_t.is_envelopedData. */ static bool is_envelopedData(private_pkcs7_t *this) { @@ -574,8 +576,9 @@ static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber, } /* decrypt the content */ + crypter->set_key(crypter, symmetric_key); crypter->decrypt(crypter, encrypted_content, iv, &this->data); - DBG4("decrypted content with padding: %B", &this->data); + DBG3("decrypted content with padding: %B", &this->data); /* remove the padding */ { @@ -611,7 +614,7 @@ failed: } /** - * Implements pkcs7_t.get_data + * Implements pkcs7_t.get_data. */ static chunk_t get_data(private_pkcs7_t *this) { @@ -619,7 +622,49 @@ static chunk_t get_data(private_pkcs7_t *this) } /** - * Implements pkcs_t.create_crluri_iterator + * Implements pkcs7_t.get_contentInfo. + */ +static chunk_t get_contentInfo(private_pkcs7_t *this) +{ + chunk_t content_type; + + /* select DER-encoded OID for pkcs7_contentInfo type */ + switch(this->type) + { + case OID_PKCS7_DATA: + content_type = ASN1_pkcs7_data_oid; + break; + case OID_PKCS7_SIGNED_DATA: + content_type = ASN1_pkcs7_signed_data_oid; + break; + case OID_PKCS7_ENVELOPED_DATA: + content_type = ASN1_pkcs7_enveloped_data_oid; + break; + case OID_PKCS7_SIGNED_ENVELOPED_DATA: + content_type = ASN1_pkcs7_signed_enveloped_data_oid; + break; + case OID_PKCS7_DIGESTED_DATA: + content_type = ASN1_pkcs7_digested_data_oid; + break; + case OID_PKCS7_ENCRYPTED_DATA: + content_type = ASN1_pkcs7_encrypted_data_oid; + break; + case OID_UNKNOWN: + default: + DBG1("invalid pkcs7 contentInfo type"); + return chunk_empty; + } + + return (this->content.ptr == NULL) + ? asn1_simple_object(ASN1_SEQUENCE, content_type) + : asn1_wrap(ASN1_SEQUENCE, "cc", + content_type, + asn1_simple_object(ASN1_CONTEXT_C_0, this->content) + ); +} + +/** + * Implements pkcs7_t.create_certificate_iterator */ static iterator_t *create_certificate_iterator(const private_pkcs7_t *this) { @@ -627,6 +672,138 @@ static iterator_t *create_certificate_iterator(const private_pkcs7_t *this) } /** + * build a DER-encoded issuerAndSerialNumber object + */ +chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert) +{ + return asn1_wrap(ASN1_SEQUENCE, "cm", + cert->get_issuer(cert), + asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert))); +} + +/** + * Implements pkcs7_t.build_envelopedData. + */ +bool build_envelopedData(private_pkcs7_t *this, x509_t *cert, + encryption_algorithm_t alg) +{ + chunk_t iv, symmetricKey, out, alg_oid; + crypter_t *crypter; + + /* select OID of symmetric encryption algorithm */ + switch (alg) + { + case ENCR_DES: + alg_oid = ASN1_des_cbc_oid; + break; + case ENCR_3DES: + alg_oid = ASN1_3des_ede_cbc_oid; + break; + default: + return FALSE; + } + + crypter = crypter_create(alg, 0); + if (crypter == NULL) + { + DBG1("could not create crypter for algorithm %N", + encryption_algorithm_names, alg); + return FALSE; + } + + /* generate a true random symmetric encryption key + * and a pseudo-random iv + */ + { + randomizer_t *randomizer = randomizer_create(); + + randomizer->allocate_random_bytes(randomizer, + crypter->get_key_size(crypter), &symmetricKey); + DBG4("symmetric encryption key: %B", &symmetricKey); + + randomizer->allocate_pseudo_random_bytes(randomizer, + crypter->get_block_size(crypter), &iv); + DBG4("initialization vector: %B", &iv); + + randomizer->destroy(randomizer); + } + + /* pad the data so that the total length becomes + * a multiple of the block size + */ + { + size_t block_size = crypter->get_block_size(crypter); + size_t padding = this->data.len % block_size; + + if (padding == 0) + { + padding += block_size; + } + + out.len = this->data.len + padding; + out.ptr = malloc(out.len); + + DBG2("padding %d bytes of data to multiple block size of %d bytes", + (int)this->data.len, (int)out.len); + + /* copy data */ + memcpy(out.ptr, this->data.ptr, this->data.len); + /* append padding */ + memset(out.ptr + this->data.len, padding, padding); + } + DBG3("padded unencrypted data: %B", &out); + + /* symmetric encryption of data object */ + crypter->set_key(crypter, symmetricKey); + crypter->encrypt(crypter, this->data, iv, &out); + crypter->destroy(crypter); + DBG3("encrypted data: %B", &out); + + /* build pkcs7 enveloped data object */ + { + chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm", + alg_oid, + asn1_wrap(ASN1_OCTET_STRING, "m", iv)); + + chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm", + ASN1_pkcs7_data_oid, + contentEncryptionAlgorithm, + asn1_wrap(ASN1_CONTEXT_S_0, "m", out)); + + chunk_t wrappedKey, encryptedKey, recipientInfo; + + rsa_public_key_t *public_key = cert->get_public_key(cert); + + public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey); + chunk_free_randomized(&symmetricKey); + + encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey); + + recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm", + ASN1_INTEGER_0, + pkcs7_build_issuerAndSerialNumber(cert), + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + encryptedKey); + + this->content = asn1_wrap(ASN1_SEQUENCE, "cmm", + ASN1_INTEGER_0, + asn1_wrap(ASN1_SET, "m", recipientInfo), + encryptedContentInfo); + this->type = OID_PKCS7_ENVELOPED_DATA; + } + return TRUE; +} + +/** + * Implements pkcs7_t.build_signedData. + */ +bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *key, + hash_algorithm_t alg) +{ + return FALSE; +} + +/** * Implements pkcs7_t.destroy */ static void destroy(private_pkcs7_t *this) @@ -674,10 +851,10 @@ static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo return TRUE; } -/* - * Described in header. +/** + * Generic private constructor */ -pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) +static private_pkcs7_t *pkcs7_create_empty(void) { private_pkcs7_t *this = malloc_thing(private_pkcs7_t); @@ -685,7 +862,7 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) this->type = OID_UNKNOWN; this->content = chunk_empty; this->parsed = FALSE; - this->level = level + 2; + this->level = 0; this->data = chunk_empty; this->attributes = chunk_empty; this->certs = linked_list_create(); @@ -698,9 +875,23 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData; this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData; this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data; + this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo; this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator; + this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData; + this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData; this->public.destroy = (void (*) (pkcs7_t*))destroy; + return this; +} + +/* + * Described in header. + */ +pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) +{ + private_pkcs7_t *this = pkcs7_create_empty(); + + this->level = level + 2; if (!parse_contentInfo(chunk, level, this)) { destroy(this); @@ -708,3 +899,18 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) } return &this->public; } + +/* + * Described in header. + */ +pkcs7_t *pkcs7_create_from_data(chunk_t data, chunk_t attributes, x509_t *cert) +{ + private_pkcs7_t *this = pkcs7_create_empty(); + + this->data = chunk_clone(data); + this->attributes = attributes; + this->certs->insert_last(this->certs, cert); + this->parsed = TRUE; + + return &this->public; +} diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h index 9886e7779..8e5166d5c 100644 --- a/src/libstrongswan/crypto/pkcs7.h +++ b/src/libstrongswan/crypto/pkcs7.h @@ -7,7 +7,7 @@ /* * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2007 Andreas Steffen + * Copyright (C) 2002-2008 Andreas Steffen * * Hochschule fuer Technik Rapperswil, Switzerland * @@ -32,6 +32,7 @@ typedef struct pkcs7_t pkcs7_t; #include <library.h> #include <crypto/x509.h> #include <crypto/rsa/rsa_private_key.h> +#include <crypto/crypters/crypter.h> #include <utils/iterator.h> /** @@ -39,6 +40,7 @@ typedef struct pkcs7_t pkcs7_t; * * @b Constructors: * -pkcs7_create_from_chunk() + * -pkcs7_create() * * @ingroup crypto */ @@ -103,6 +105,14 @@ struct pkcs7_t { chunk_t (*get_data) (pkcs7_t *this); /** + * @brief Returns the a DER-encoded contentInfo object + * + * @param this calling object + * @return chunk containing the contentInfo object + */ + chunk_t (*get_contentInfo) (pkcs7_t *this); + + /** * @brief Create an iterator for the certificates. * * @param this calling object @@ -111,6 +121,26 @@ struct pkcs7_t { iterator_t *(*create_certificate_iterator) (pkcs7_t *this); /** + * @brief Build an envelopedData object + * + * @param this PKCS#7 data object to envelop + * @param cert receivers's certificate + * @param alg encryption algorithm + * @return TRUE if build was successful + */ + bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg); + + /** + * @brief Build an signedData object + * + * @param this PKCS#7 data object to sign + * @param key signer's RSA private key + * @param alg digest algorithm used for signature + * @return TRUE if build was successful + */ + bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg); + + /** * @brief Destroys the contentInfo object. * * @param this PKCS#7 contentInfo object to destroy @@ -129,4 +159,16 @@ struct pkcs7_t { */ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level); +/** + * @brief Create a PKCS#7 contentInfo object + * + * @param chunk chunk containing data + * @param attributes chunk containing attributes + * @param cert certificate to be included in the pkcs7_contentInfo object + * @return created pkcs7_contentInfo object. + * + * @ingroup crypto + */ +pkcs7_t *pkcs7_create_from_data(chunk_t data, chunk_t attributes, x509_t *cert); + #endif /* _PKCS7_H */ diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c index 40c63fa61..efbe8e86f 100644 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.c +++ b/src/libstrongswan/crypto/rsa/rsa_private_key.c @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -202,7 +204,7 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, if (status != SUCCESS) { randomizer->destroy(randomizer); - mpz_clear_randomized(*prime); + mpz_clear(*prime); return FAILED; } @@ -219,7 +221,7 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, chunk_free_randomized(&random_bytes); } /* check if it isnt too large */ - while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_len); + while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len); randomizer->destroy(randomizer); return SUCCESS; @@ -308,47 +310,14 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, chunk_t data, chunk_t *signature) { hasher_t *hasher; - chunk_t em, digestInfo, hash_id, hash; - - /* get oid string prepended to hash */ - switch (hash_algorithm) - { - case HASH_MD2: - { - hash_id =ASN1_md2_id; - break; - } - case HASH_MD5: - { - hash_id = ASN1_md5_id; - break; - } - case HASH_SHA1: - { - hash_id = ASN1_sha1_id; - break; - } - case HASH_SHA256: - { - hash_id = ASN1_sha256_id; - break; - } - case HASH_SHA384: - { - hash_id = ASN1_sha384_id; - break; - } - case HASH_SHA512: - { - hash_id = ASN1_sha512_id; - break; - } - default: - { - return NOT_SUPPORTED; - } + chunk_t em, digestInfo, hash; + int hash_oid = hasher_algorithm_to_oid(hash_algorithm); + + if (hash_oid == OID_UNKNOWN) + { + return NOT_SUPPORTED; } - + /* get hasher */ hasher = hasher_create(hash_algorithm); if (hasher == NULL) @@ -362,7 +331,7 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, /* build DER-encoded digestInfo */ digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm", - hash_id, + asn1_algorithmIdentifier(hash_oid), asn1_simple_object(ASN1_OCTET_STRING, hash) ); chunk_free(&hash); diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h index f5ff335af..5f6645809 100644 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.h +++ b/src/libstrongswan/crypto/rsa/rsa_private_key.h @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c index 4ce365e90..2105d8ffe 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.c +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.c @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -295,19 +297,13 @@ static size_t get_keysize(const private_rsa_public_key_t *this) */ chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e) { - chunk_t rawKey = asn1_wrap(ASN1_SEQUENCE, "mm", + chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_integer_from_mpz(n), asn1_integer_from_mpz(e)); - chunk_t publicKey; - - u_char *pos = build_asn1_object(&publicKey, ASN1_BIT_STRING, 1 + rawKey.len); - - *pos++ = 0x00; - memcpy(pos, rawKey.ptr, rawKey.len); - free(rawKey.ptr); - return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_rsaEncryption_id, - publicKey); + return asn1_wrap(ASN1_SEQUENCE, "cm", + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + asn1_bitstring("m", publicKey)); } /** diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h index 3a034633b..1c15169fd 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.h +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.h @@ -6,8 +6,10 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2007-2008 Andreas Steffen + * * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c index 022f15c93..ff490a095 100755 --- a/src/libstrongswan/crypto/x509.c +++ b/src/libstrongswan/crypto/x509.c @@ -1381,39 +1381,14 @@ static chunk_t x509_build_tbs(private_x509_t *this) static void build_encoding(private_x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key) { - switch (alg) - { - case HASH_MD5: - this->signatureAlgorithm = OID_MD5_WITH_RSA; - break; - case HASH_SHA1: - default: - this->signatureAlgorithm = OID_SHA1_WITH_RSA; - break; - case HASH_SHA256: - this->signatureAlgorithm = OID_SHA256_WITH_RSA; - break; - case HASH_SHA384: - this->signatureAlgorithm = OID_SHA384_WITH_RSA; - break; - case HASH_SHA512: - this->signatureAlgorithm = OID_SHA512_WITH_RSA; - } - this->tbsCertificate = x509_build_tbs(this); - { - chunk_t rawSignature; - u_char *pos; - - private_key->build_emsa_pkcs1_signature(private_key, alg, - this->tbsCertificate, &rawSignature); + chunk_t signature; - pos = build_asn1_object(&this->signature, ASN1_BIT_STRING, - 1 + rawSignature.len); - *pos++ = 0x00; - memcpy(pos, rawSignature.ptr, rawSignature.len); - free(rawSignature.ptr); - } - this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm", + this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg); + this->tbsCertificate = x509_build_tbs(this); + private_key->build_emsa_pkcs1_signature(private_key, alg, + this->tbsCertificate, &signature); + this->signature = asn1_bitstring("m", signature); + this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm", this->tbsCertificate, asn1_algorithmIdentifier(this->signatureAlgorithm), this->signature); |