4 #include <openssl/bio.h>
5 #include <openssl/cms.h>
6 #include <openssl/crypto.h>
7 #include <openssl/err.h>
8 #include <openssl/evp.h>
9 #include <openssl/pkcs7.h>
10 #include <openssl/x509.h>
12 #include "isds_priv.h"
16 #ifndef SHA1_DIGEST_LENGTH
17 # define SHA1_DIGEST_LENGTH 20
18 #endif /* !SHA1_DIGEST_LENGTH */
21 /* Initialise all cryptographic libraries which libisds depends on.
22 * @return IE_SUCCESS if everything went all-right. */
23 _hidden isds_error
_isds_init_crypto(void)
25 OpenSSL_add_all_digests(); /* Loads all digest algorithms. */
27 ERR_load_crypto_strings();
28 //ERR_load_CMS_strings();
30 version_openssl
= SSLeay_version(SSLEAY_VERSION
);
35 /* Computes hash from @input with @length and store it into @hash.
36 * The hash algorithm is defined inside @hash.
37 * @input is input block to hash
38 * @length is @input block length in bytes
39 * @hash input algorithm, output hash value and hash length; hash value will be
40 * reallocated, it's always valid pointer or NULL (before and after call) */
41 _hidden isds_error
_isds_compute_hash(const void *input
,
42 const size_t length
, struct isds_hash
*hash
)
44 isds_error retval
= IE_SUCCESS
;
45 void *hash_buf
= NULL
;
47 EVP_MD_CTX
*mdctx
= NULL
;
48 const char *hash_name
= NULL
;
52 if (((0 != length
) && (NULL
== input
)) || (NULL
== hash
)) {
56 isds_log(ILF_SEC
, ILL_DEBUG
,
57 _("Data hash requested, length=%zu, content:\n%*s\n"
58 "End of data to hash\n"), length
, length
, input
);
60 /* Select algorithm */
61 switch (hash
->algorithm
) {
62 case HASH_ALGORITHM_MD5
: hash_name
= "MD5"; break;
63 case HASH_ALGORITHM_SHA_1
: hash_name
= "SHA1"; break;
64 case HASH_ALGORITHM_SHA_224
: hash_name
= "SHA224"; break;
65 case HASH_ALGORITHM_SHA_256
: hash_name
= "SHA256"; break;
66 case HASH_ALGORITHM_SHA_384
: hash_name
= "SHA384"; break;
67 case HASH_ALGORITHM_SHA_512
: hash_name
= "SHA512"; break;
73 md
= EVP_get_digestbyname(hash_name
);
79 mdctx
= malloc(sizeof(*mdctx
));
84 EVP_MD_CTX_init(mdctx
);
85 if (!EVP_DigestInit(mdctx
, md
)) {
89 if (!EVP_DigestUpdate(mdctx
, input
, length
)) {
94 hash_len
= EVP_MD_size(md
);
95 hash_buf
= realloc(hash
->value
, hash_len
);
96 if (NULL
== hash_buf
) {
100 hash
->value
= hash_buf
;
101 hash
->length
= hash_len
;
103 if (!EVP_DigestFinal_ex(mdctx
, hash
->value
, &md_len
)) {
108 EVP_MD_CTX_cleanup(mdctx
); free(mdctx
); mdctx
= NULL
;
114 EVP_MD_CTX_cleanup(mdctx
); free(mdctx
);
119 /* Free CMS data buffer allocated inside _isds_extract_cms_data().
120 * This is necessary because GPGME.
121 * @buffer is pointer to memory to free */
122 _hidden
void _isds_cms_data_free(void *buffer
)
127 /* Extract data from CMS (successor of PKCS#7)
128 * The CMS' signature is is not verified.
129 * @context is session context
130 * @cms is input block with CMS structure
131 * @cms_length is @cms block length in bytes
132 * @data are automatically reallocated bit stream with data found in @cms
133 * You must free them with _isds_cms_data_free().
134 * @data_length is length of @data in bytes */
135 _hidden isds_error
_isds_extract_cms_data(struct isds_ctx
*context
,
136 const void *cms
, const size_t cms_length
,
137 void **data
, size_t *data_length
)
140 isds_error retval
= IE_SUCCESS
;
142 CMS_ContentInfo
*cms_ci
= NULL
;
143 const ASN1_OBJECT
*asn1_obj
;
144 ASN1_OCTET_STRING
**pos
;
148 assert(NULL
!= context
);
150 if ((NULL
== cms
) || (0 == cms_length
) ||
151 (NULL
== data
) || (NULL
== data_length
)) {
158 bio
= BIO_new_mem_buf((void *) cms
, cms_length
);
160 isds_log_message(context
, _("Creating CMS reader BIO failed"));
161 while (0 != (err
= ERR_get_error())) {
162 locale_str
= _isds_utf82locale(ERR_error_string(err
, NULL
));
163 if (NULL
!= locale_str
) {
164 isds_log_message(context
, locale_str
);
172 cms_ci
= d2i_CMS_bio(bio
, NULL
);
173 if (NULL
== cms_ci
) {
174 isds_log_message(context
, _("Cannot parse CMS"));
175 while (0 != (err
= ERR_get_error())) {
176 locale_str
= _isds_utf82locale(ERR_error_string(err
, NULL
));
177 if (NULL
!= locale_str
) {
178 isds_log_message(context
, locale_str
);
186 BIO_free(bio
); bio
= NULL
;
188 asn1_obj
= CMS_get0_type(cms_ci
);
189 nid
= OBJ_obj2nid(asn1_obj
);
192 case NID_id_smime_ct_compressedData
:
193 case NID_id_smime_ct_authData
:
194 case NID_pkcs7_enveloped
:
195 case NID_pkcs7_encrypted
:
196 case NID_pkcs7_digest
:
201 case NID_pkcs7_signed
:
210 pos
= CMS_get0_content(cms_ci
);
211 if ((NULL
== pos
) || (NULL
== *pos
)) {
217 *data
= malloc((*pos
)->length
);
222 *data_length
= (*pos
)->length
;
223 memcpy(*data
, (*pos
)->data
, (*pos
)->length
);
225 CMS_ContentInfo_free(cms_ci
); cms_ci
= NULL
;
233 if (NULL
!= cms_ci
) {
234 CMS_ContentInfo_free(cms_ci
);