4 #include <openssl/bio.h>
5 #include <openssl/cms.h>
6 #include <openssl/crypto.h>
7 #include <openssl/err.h>
8 #include <openssl/md5.h>
9 #include <openssl/pkcs7.h>
10 #include <openssl/sha.h>
11 #include <openssl/x509.h>
13 #include "isds_priv.h"
17 #ifndef SHA1_DIGEST_LENGTH
18 # define SHA1_DIGEST_LENGTH 20
19 #endif /* !SHA1_DIGEST_LENGTH */
22 /* Initialise all cryptographic libraries which libisds depends on.
23 * @return IE_SUCCESS if everything went all-right. */
24 _hidden isds_error
_isds_init_crypto(void)
26 ERR_load_crypto_strings();
27 //ERR_load_CMS_strings();
29 version_openssl
= SSLeay_version(SSLEAY_VERSION
);
34 /* Computes hash from @input with @length and store it into @hash.
35 * The hash algorithm is defined inside @hash.
36 * @input is input block to hash
37 * @length is @input block length in bytes
38 * @hash input algorithm, output hash value and hash length; hash value will be
39 * reallocated, it's always valid pointer or NULL (before and after call) */
40 _hidden isds_error
_isds_compute_hash(const void *input
,
41 const size_t length
, struct isds_hash
*hash
)
43 void *hash_buf
= NULL
;
45 unsigned char * (*hash_func
)(const unsigned char *, size_t n
,
46 unsigned char *) = NULL
;
48 if (((0 != length
) && (NULL
== input
)) || (NULL
== hash
)) {
52 isds_log(ILF_SEC
, ILL_DEBUG
,
53 _("Data hash requested, length=%zu, content:\n%*s\n"
54 "End of data to hash\n"), length
, length
, input
);
56 /* Select algorithm */
57 switch (hash
->algorithm
) {
58 case HASH_ALGORITHM_MD5
:
59 hash_len
= MD5_DIGEST_LENGTH
;
62 case HASH_ALGORITHM_SHA_1
:
63 hash_len
= SHA1_DIGEST_LENGTH
;
66 case HASH_ALGORITHM_SHA_224
:
67 hash_len
= SHA224_DIGEST_LENGTH
;
70 case HASH_ALGORITHM_SHA_256
:
71 hash_len
= SHA256_DIGEST_LENGTH
;
74 case HASH_ALGORITHM_SHA_384
:
75 hash_len
= SHA384_DIGEST_LENGTH
;
78 case HASH_ALGORITHM_SHA_512
:
79 hash_len
= SHA512_DIGEST_LENGTH
;
86 /* Get known the hash length and allocate buffer for hash value */
87 hash
->length
= hash_len
;
88 hash_buf
= realloc(hash
->value
, hash
->length
);
89 if (NULL
== hash_buf
) {
92 hash
->value
= hash_buf
;
94 assert(NULL
!= hash
->value
);
95 assert(NULL
!= hash_func
);
97 /* Compute the hash */
98 hash_func(input
, length
, hash
->value
);
103 /* Free CMS data buffer allocated inside _isds_extract_cms_data().
104 * This is necessary because GPGME.
105 * @buffer is pointer to memory to free */
106 _hidden
void _isds_cms_data_free(void *buffer
)
111 /* Extract data from CMS (successor of PKCS#7)
112 * @context is session context
113 * @cms is input block with CMS structure
114 * @cms_length is @cms block length in bytes
115 * @data are automatically reallocated bit stream with data found in @cms
116 * You must free them with _isds_cms_data_free().
117 * @data_length is length of @data in bytes */
118 _hidden isds_error
_isds_extract_cms_data(struct isds_ctx
*context
,
119 const void *cms
, const size_t cms_length
,
120 void **data
, size_t *data_length
)
123 isds_error retval
= IE_SUCCESS
;
125 CMS_ContentInfo
*cms_ci
= NULL
;
126 const ASN1_OBJECT
*asn1_obj
;
127 ASN1_OCTET_STRING
**pos
;
131 assert(NULL
!= context
);
133 if ((NULL
== cms
) || (0 == cms_length
) ||
134 (NULL
== data
) || (NULL
== data_length
)) {
141 bio
= BIO_new_mem_buf((void *) cms
, cms_length
);
143 isds_log_message(context
, _("Creating CMS reader BIO failed."));
144 while (0 != (err
= ERR_get_error())) {
145 locale_str
= _isds_utf82locale(ERR_error_string(err
, NULL
));
146 if (NULL
!= locale_str
) {
147 isds_log_message(context
, locale_str
);
155 cms_ci
= d2i_CMS_bio(bio
, NULL
);
156 if (NULL
== cms_ci
) {
157 fprintf(stderr
, "Cannot parse CMS.\n");
158 isds_log_message(context
, _("Cannot parse CMS."));
159 while (0 != (err
= ERR_get_error())) {
160 locale_str
= _isds_utf82locale(ERR_error_string(err
, NULL
));
161 if (NULL
!= locale_str
) {
162 isds_log_message(context
, locale_str
);
170 BIO_free(bio
); bio
= NULL
;
172 asn1_obj
= CMS_get0_type(cms_ci
);
173 nid
= OBJ_obj2nid(asn1_obj
);
176 case NID_id_smime_ct_compressedData
:
177 case NID_id_smime_ct_authData
:
178 case NID_pkcs7_enveloped
:
179 case NID_pkcs7_encrypted
:
180 case NID_pkcs7_digest
:
185 case NID_pkcs7_signed
:
186 pos
= CMS_get0_content(cms_ci
);
187 if ((NULL
== pos
) || (NULL
== *pos
)) {
200 *data
= malloc((*pos
)->length
);
205 *data_length
= (*pos
)->length
;
206 memcpy(*data
, (*pos
)->data
, (*pos
)->length
);
208 CMS_ContentInfo_free(cms_ci
); cms_ci
= NULL
;
216 if (NULL
!= cms_ci
) {
217 CMS_ContentInfo_free(cms_ci
);