-/* 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
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,
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[] = {
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;
}
}
/**
+ * 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').
*/
{
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);
-/* 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
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);
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 */
*/
/*
- * 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
/*
* 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;
*/
/*
- * 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
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
*/
/* 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
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));
/*
* 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
#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"
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)
{
}
/**
- * Implements pkcs7_t.is_signedData.
+ * Implements pkcs7_t.is_envelopedData.
*/
static bool is_envelopedData(private_pkcs7_t *this)
{
}
/* 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 */
{
}
/**
- * Implements pkcs7_t.get_data
+ * Implements pkcs7_t.get_data.
*/
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)
{
}
/**
+ * 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)
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);
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();
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);
}
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;
+}
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2007 Andreas Steffen
+ * Copyright (C) 2002-2008 Andreas Steffen
*
* Hochschule fuer Technik Rapperswil, Switzerland
*
#include <library.h>
#include <crypto/x509.h>
#include <crypto/rsa/rsa_private_key.h>
+#include <crypto/crypters/crypter.h>
#include <utils/iterator.h>
/**
*
* @b Constructors:
* -pkcs7_create_from_chunk()
+ * -pkcs7_create()
*
* @ingroup crypto
*/
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
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
*/
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 */
*/
/*
- * 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
if (status != SUCCESS)
{
randomizer->destroy(randomizer);
- mpz_clear_randomized(*prime);
+ mpz_clear(*prime);
return FAILED;
}
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;
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)
/* 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);
*/
/*
- * 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
*/
/*
- * 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
*/
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));
}
/**
*/
/*
- * 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
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);