2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2008 Tobias Brunner
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "openssl_util.h"
21 #include <openssl/evp.h>
22 #include <openssl/x509.h>
25 * Described in header.
27 bool openssl_hash_chunk(int hash_type
, chunk_t data
, chunk_t
*hash
)
31 const EVP_MD
*hasher
= EVP_get_digestbynid(hash_type
);
37 ctx
= EVP_MD_CTX_create();
43 if (!EVP_DigestInit_ex(ctx
, hasher
, NULL
))
48 if (!EVP_DigestUpdate(ctx
, data
.ptr
, data
.len
))
53 *hash
= chunk_alloc(hasher
->md_size
);
54 if (!EVP_DigestFinal_ex(ctx
, hash
->ptr
, NULL
))
64 EVP_MD_CTX_destroy(ctx
);
70 * Described in header.
72 bool openssl_bn_cat(int len
, BIGNUM
*a
, BIGNUM
*b
, chunk_t
*chunk
)
76 chunk
->len
= len
+ (b ? len
: 0);
77 chunk
->ptr
= malloc(chunk
->len
);
78 memset(chunk
->ptr
, 0, chunk
->len
);
81 offset
= len
- BN_num_bytes(a
);
82 if (!BN_bn2bin(a
, chunk
->ptr
+ offset
))
87 /* optionally convert and concatenate b */
90 offset
= len
- BN_num_bytes(b
);
91 if (!BN_bn2bin(b
, chunk
->ptr
+ len
+ offset
))
105 * Described in header.
107 bool openssl_bn_split(chunk_t chunk
, BIGNUM
*a
, BIGNUM
*b
)
111 if ((chunk
.len
% 2) != 0)
118 if (!BN_bin2bn(chunk
.ptr
, len
, a
) ||
119 !BN_bin2bn(chunk
.ptr
+ len
, len
, b
))
128 * Build fingerprints of a private/public RSA key.
130 static bool build_fingerprint(chunk_t key
, key_encoding_type_t type
, int nid
,
131 chunk_t
*fingerprint
)
135 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
138 DBG1("SHA1 hash algorithm not supported, fingerprinting failed");
141 if (type
== KEY_ID_PUBKEY_INFO_SHA1
)
147 /* wrap publicKey in subjectPublicKeyInfo */
148 pubkey
= X509_PUBKEY_new();
149 ASN1_OBJECT_free(pubkey
->algor
->algorithm
);
150 pubkey
->algor
->algorithm
= OBJ_nid2obj(nid
);
152 if (pubkey
->algor
->parameter
== NULL
||
153 pubkey
->algor
->parameter
->type
!= V_ASN1_NULL
)
155 ASN1_TYPE_free(pubkey
->algor
->parameter
);
156 pubkey
->algor
->parameter
= ASN1_TYPE_new();
157 pubkey
->algor
->parameter
->type
= V_ASN1_NULL
;
159 M_ASN1_BIT_STRING_set(pubkey
->public_key
, enc
.ptr
, enc
.len
);
161 enc
= chunk_alloc(i2d_X509_PUBKEY(pubkey
, NULL
));
163 i2d_X509_PUBKEY(pubkey
, &p
);
164 X509_PUBKEY_free(pubkey
);
166 hasher
->allocate_hash(hasher
, enc
, fingerprint
);
171 hasher
->allocate_hash(hasher
, key
, fingerprint
);
173 hasher
->destroy(hasher
);
180 bool openssl_encode(key_encoding_type_t type
, chunk_t
*encoding
, va_list args
)
186 case KEY_PUB_ASN1_DER
:
187 if (key_encoding_args(args
, KEY_PART_RSA_PUB_ASN1_DER
, &key
,
189 key_encoding_args(args
, KEY_PART_ECDSA_PUB_ASN1_DER
, &key
,
192 *encoding
= chunk_clone(key
);
196 case KEY_PRIV_ASN1_DER
:
197 if (key_encoding_args(args
, KEY_PART_RSA_PRIV_ASN1_DER
, &key
,
199 key_encoding_args(args
, KEY_PART_ECDSA_PRIV_ASN1_DER
, &key
,
202 *encoding
= chunk_clone(key
);
206 case KEY_ID_PUBKEY_SHA1
:
207 case KEY_ID_PUBKEY_INFO_SHA1
:
208 if (key_encoding_args(args
, KEY_PART_RSA_PUB_ASN1_DER
, &key
,
211 return build_fingerprint(key
, type
, NID_rsaEncryption
, encoding
);
213 else if (key_encoding_args(args
, KEY_PART_ECDSA_PUB_ASN1_DER
, &key
,
216 return build_fingerprint(key
, type
, NID_X9_62_id_ecPublicKey
,