2 * crypto.c Encryption support functions
4 * Author: Landon Fuller <landonf@opendarwin.org>
8 * Copyright (C) 2005 Kern Sibbald
10 * This file was contributed to the Bacula project by Landon Fuller.
12 * Landon Fuller has been granted a perpetual, worldwide, non-exclusive,
13 * no-charge, royalty-free, irrevocable copyright license to reproduce,
14 * prepare derivative works of, publicly display, publicly perform,
15 * sublicense, and distribute the original work contributed by Landon Fuller
16 * to the Bacula project in source or object form.
18 * If you wish to license these contributions under an alternate open source
19 * license please contact Landon Fuller <landonf@opendarwin.org>.
22 Copyright (C) 2005 Kern Sibbald
24 This program is free software; you can redistribute it and/or
25 modify it under the terms of the GNU General Public License
26 version 2 as amended with additional clauses defined in the
27 file LICENSE in the main source directory.
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 the file LICENSE for additional details.
44 * Prefix: iso.org.dod.internet.private.enterprise.threerings.external.bacula (1.3.6.1.4.1.22054.500.2)
45 * Organization: Bacula Project
46 * Contact Name: Kern Sibbald
47 * Contact E-mail: kern@sibbald.com
49 * Top Level Allocations - 500.2
50 * 1 - Published Allocations
51 * 1.1 - Bacula Encryption
53 * Bacula Encryption - 500.2.1.1
56 * 2 - ASN.1 Object Identifiers
62 * BaculaCrypto { iso(1) identified-organization(3) usdod(6)
63 * internet(1) private(4) enterprises(1) three-rings(22054)
64 * external(500) bacula(2) published(1) bacula-encryption(1)
65 * asn1-modules(1) bacula-crypto(1) }
67 * DEFINITIONS AUTOMATIC TAGS ::=
70 * SignatureData ::= SEQUENCE {
71 * version Version DEFAULT v0,
72 * signerInfo SignerInfo }
74 * CryptoData ::= SEQUENCE {
75 * version Version DEFAULT v0,
76 * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
77 * iv InitializationVector,
78 * recipientInfo RecipientInfo
81 * SignerInfo ::= SET OF SignerInfo
82 * RecipientInfo ::= SET OF RecipientInfo
84 * Version ::= INTEGER { v0(0) }
86 * SignerInfo ::= SEQUENCE {
88 * subjectKeyIdentifier SubjectKeyIdentifier,
89 * digestAlgorithm DigestAlgorithmIdentifier,
90 * signatureAlgorithm SignatureAlgorithmIdentifier,
91 * signature SignatureValue }
93 * RecipientInfo ::= SEQUENCE {
95 * subjectKeyIdentifier SubjectKeyIdentifier
96 * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
97 * encryptedKey EncryptedKey
100 * SubjectKeyIdentifier ::= OCTET STRING
102 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
104 * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
106 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
108 * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
110 * InitializationVector ::= OCTET STRING
112 * SignatureValue ::= OCTET STRING
114 * EncryptedKey ::= OCTET STRING
116 * AlgorithmIdentifier ::= OBJECT IDENTIFIER
121 #ifdef HAVE_CRYPTO /* Is encryption enabled? */
122 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
124 /* Are we initialized? */
125 static int crypto_initialized = false;
127 /* ASN.1 Declarations */
128 #define BACULA_ASN1_VERSION 0
131 ASN1_INTEGER *version;
132 ASN1_OCTET_STRING *subjectKeyIdentifier;
133 ASN1_OBJECT *digestAlgorithm;
134 ASN1_OBJECT *signatureAlgorithm;
135 ASN1_OCTET_STRING *signature;
139 ASN1_INTEGER *version;
140 ASN1_OCTET_STRING *subjectKeyIdentifier;
141 ASN1_OBJECT *keyEncryptionAlgorithm;
142 ASN1_OCTET_STRING *encryptedKey;
145 ASN1_SEQUENCE(SignerInfo) = {
146 ASN1_SIMPLE(SignerInfo, version, ASN1_INTEGER),
147 ASN1_SIMPLE(SignerInfo, subjectKeyIdentifier, ASN1_OCTET_STRING),
148 ASN1_SIMPLE(SignerInfo, digestAlgorithm, ASN1_OBJECT),
149 ASN1_SIMPLE(SignerInfo, signatureAlgorithm, ASN1_OBJECT),
150 ASN1_SIMPLE(SignerInfo, signature, ASN1_OCTET_STRING)
151 } ASN1_SEQUENCE_END(SignerInfo);
153 ASN1_SEQUENCE(RecipientInfo) = {
154 ASN1_SIMPLE(RecipientInfo, version, ASN1_INTEGER),
155 ASN1_SIMPLE(RecipientInfo, subjectKeyIdentifier, ASN1_OCTET_STRING),
156 ASN1_SIMPLE(RecipientInfo, keyEncryptionAlgorithm, ASN1_OBJECT),
157 ASN1_SIMPLE(RecipientInfo, encryptedKey, ASN1_OCTET_STRING),
158 } ASN1_SEQUENCE_END(RecipientInfo);
161 ASN1_INTEGER *version;
162 STACK_OF(SignerInfo) *signerInfo;
166 ASN1_INTEGER *version;
167 ASN1_OBJECT *contentEncryptionAlgorithm;
168 ASN1_OCTET_STRING *iv;
169 STACK_OF(RecipientInfo) *recipientInfo;
172 ASN1_SEQUENCE(SignatureData) = {
173 ASN1_SIMPLE(SignatureData, version, ASN1_INTEGER),
174 ASN1_SET_OF(SignatureData, signerInfo, SignerInfo),
175 } ASN1_SEQUENCE_END(SignatureData);
177 ASN1_SEQUENCE(CryptoData) = {
178 ASN1_SIMPLE(CryptoData, version, ASN1_INTEGER),
179 ASN1_SIMPLE(CryptoData, iv, ASN1_OCTET_STRING),
180 ASN1_SET_OF(CryptoData, recipientInfo, RecipientInfo)
181 } ASN1_SEQUENCE_END(CryptoData);
183 IMPLEMENT_ASN1_FUNCTIONS(SignerInfo)
184 IMPLEMENT_ASN1_FUNCTIONS(RecipientInfo)
185 IMPLEMENT_ASN1_FUNCTIONS(SignatureData)
186 IMPLEMENT_ASN1_FUNCTIONS(CryptoData)
187 IMPLEMENT_STACK_OF(SignerInfo)
188 IMPLEMENT_STACK_OF(RecipientInfo)
191 * SignerInfo and RecipientInfo stack macros, generated by OpenSSL's util/mkstack.pl.
193 #define sk_SignerInfo_new(st) SKM_sk_new(SignerInfo, (st))
194 #define sk_SignerInfo_new_null() SKM_sk_new_null(SignerInfo)
195 #define sk_SignerInfo_free(st) SKM_sk_free(SignerInfo, (st))
196 #define sk_SignerInfo_num(st) SKM_sk_num(SignerInfo, (st))
197 #define sk_SignerInfo_value(st, i) SKM_sk_value(SignerInfo, (st), (i))
198 #define sk_SignerInfo_set(st, i, val) SKM_sk_set(SignerInfo, (st), (i), (val))
199 #define sk_SignerInfo_zero(st) SKM_sk_zero(SignerInfo, (st))
200 #define sk_SignerInfo_push(st, val) SKM_sk_push(SignerInfo, (st), (val))
201 #define sk_SignerInfo_unshift(st, val) SKM_sk_unshift(SignerInfo, (st), (val))
202 #define sk_SignerInfo_find(st, val) SKM_sk_find(SignerInfo, (st), (val))
203 #define sk_SignerInfo_delete(st, i) SKM_sk_delete(SignerInfo, (st), (i))
204 #define sk_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(SignerInfo, (st), (ptr))
205 #define sk_SignerInfo_insert(st, val, i) SKM_sk_insert(SignerInfo, (st), (val), (i))
206 #define sk_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SignerInfo, (st), (cmp))
207 #define sk_SignerInfo_dup(st) SKM_sk_dup(SignerInfo, st)
208 #define sk_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(SignerInfo, (st), (free_func))
209 #define sk_SignerInfo_shift(st) SKM_sk_shift(SignerInfo, (st))
210 #define sk_SignerInfo_pop(st) SKM_sk_pop(SignerInfo, (st))
211 #define sk_SignerInfo_sort(st) SKM_sk_sort(SignerInfo, (st))
212 #define sk_SignerInfo_is_sorted(st) SKM_sk_is_sorted(SignerInfo, (st))
214 #define d2i_ASN1_SET_OF_SignerInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
215 SKM_ASN1_SET_OF_d2i(SignerInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
216 #define i2d_ASN1_SET_OF_SignerInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
217 SKM_ASN1_SET_OF_i2d(SignerInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
218 #define ASN1_seq_pack_SignerInfo(st, i2d_func, buf, len) \
219 SKM_ASN1_seq_pack(SignerInfo, (st), (i2d_func), (buf), (len))
220 #define ASN1_seq_unpack_SignerInfo(buf, len, d2i_func, free_func) \
221 SKM_ASN1_seq_unpack(SignerInfo, (buf), (len), (d2i_func), (free_func))
223 #define sk_RecipientInfo_new(st) SKM_sk_new(RecipientInfo, (st))
224 #define sk_RecipientInfo_new_null() SKM_sk_new_null(RecipientInfo)
225 #define sk_RecipientInfo_free(st) SKM_sk_free(RecipientInfo, (st))
226 #define sk_RecipientInfo_num(st) SKM_sk_num(RecipientInfo, (st))
227 #define sk_RecipientInfo_value(st, i) SKM_sk_value(RecipientInfo, (st), (i))
228 #define sk_RecipientInfo_set(st, i, val) SKM_sk_set(RecipientInfo, (st), (i), (val))
229 #define sk_RecipientInfo_zero(st) SKM_sk_zero(RecipientInfo, (st))
230 #define sk_RecipientInfo_push(st, val) SKM_sk_push(RecipientInfo, (st), (val))
231 #define sk_RecipientInfo_unshift(st, val) SKM_sk_unshift(RecipientInfo, (st), (val))
232 #define sk_RecipientInfo_find(st, val) SKM_sk_find(RecipientInfo, (st), (val))
233 #define sk_RecipientInfo_delete(st, i) SKM_sk_delete(RecipientInfo, (st), (i))
234 #define sk_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(RecipientInfo, (st), (ptr))
235 #define sk_RecipientInfo_insert(st, val, i) SKM_sk_insert(RecipientInfo, (st), (val), (i))
236 #define sk_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(RecipientInfo, (st), (cmp))
237 #define sk_RecipientInfo_dup(st) SKM_sk_dup(RecipientInfo, st)
238 #define sk_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(RecipientInfo, (st), (free_func))
239 #define sk_RecipientInfo_shift(st) SKM_sk_shift(RecipientInfo, (st))
240 #define sk_RecipientInfo_pop(st) SKM_sk_pop(RecipientInfo, (st))
241 #define sk_RecipientInfo_sort(st) SKM_sk_sort(RecipientInfo, (st))
242 #define sk_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(RecipientInfo, (st))
244 #define d2i_ASN1_SET_OF_RecipientInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
245 SKM_ASN1_SET_OF_d2i(RecipientInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
246 #define i2d_ASN1_SET_OF_RecipientInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
247 SKM_ASN1_SET_OF_i2d(RecipientInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
248 #define ASN1_seq_pack_RecipientInfo(st, i2d_func, buf, len) \
249 SKM_ASN1_seq_pack(RecipientInfo, (st), (i2d_func), (buf), (len))
250 #define ASN1_seq_unpack_RecipientInfo(buf, len, d2i_func, free_func) \
251 SKM_ASN1_seq_unpack(RecipientInfo, (buf), (len), (d2i_func), (free_func))
252 /* End of util/mkstack.pl block */
254 /* X509 Public/Private Key Pair Structure */
255 struct X509_Keypair {
256 ASN1_OCTET_STRING *keyid;
261 /* Message Digest Structure */
263 crypto_digest_t type;
267 /* Message Signature Structure */
269 SignatureData *sigData;
272 /* Encryption Session Data */
273 struct Crypto_Session {
274 CryptoData *cryptoData; /* ASN.1 Structure */
275 unsigned char *session_key; /* Private symmetric session key */
276 size_t session_key_len; /* Symmetric session key length */
279 /* Symmetric Cipher Context */
280 struct Cipher_Context {
284 /* PEM Password Dispatch Context */
285 typedef struct PEM_CB_Context {
286 CRYPTO_PEM_PASSWD_CB *pem_callback;
287 const void *pem_userdata;
291 * Extract subjectKeyIdentifier from x509 certificate.
292 * Returns: On success, an ASN1_OCTET_STRING that must be freed via M_ASN1_OCTET_STRING_free().
295 static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert){
297 X509V3_EXT_METHOD *method;
298 ASN1_OCTET_STRING *keyid;
300 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
301 const unsigned char *ext_value_data;
303 unsigned char *ext_value_data;
307 /* Find the index to the subjectKeyIdentifier extension */
308 i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
314 /* Grab the extension */
315 ext = X509_get_ext(cert, i);
317 /* Get x509 extension method structure */
318 if (!(method = X509V3_EXT_get(ext))) {
322 ext_value_data = ext->value->data;
324 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
328 /* Decode ASN1 item in data */
329 keyid = (ASN1_OCTET_STRING *) ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
330 ASN1_ITEM_ptr(method->it));
334 /* Decode ASN1 item in data */
335 keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
339 keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
346 * Create a new keypair object.
347 * Returns: A pointer to a X509 KEYPAIR object on success.
350 X509_KEYPAIR *crypto_keypair_new (void) {
351 X509_KEYPAIR *keypair;
353 /* Allocate our keypair structure */
354 keypair = (X509_KEYPAIR *) malloc(sizeof(X509_KEYPAIR));
359 /* Initialize our keypair structure */
360 keypair->keyid = NULL;
361 keypair->pubkey = NULL;
362 keypair->privkey = NULL;
368 * Create a copy of a keypair object. The underlying
369 * EVP objects are not duplicated, as no EVP_PKEY_dup()
370 * API is available. Instead, the reference count is
373 X509_KEYPAIR *crypto_keypair_dup (X509_KEYPAIR *keypair)
375 X509_KEYPAIR *newpair;
377 newpair = crypto_keypair_new();
380 /* Allocation failed */
384 /* Increment the public key ref count */
385 if (keypair->pubkey) {
386 CRYPTO_add(&(keypair->pubkey->references), 1, CRYPTO_LOCK_EVP_PKEY);
387 newpair->pubkey = keypair->pubkey;
390 /* Increment the private key ref count */
391 if (keypair->privkey) {
392 CRYPTO_add(&(keypair->privkey->references), 1, CRYPTO_LOCK_EVP_PKEY);
393 newpair->privkey = keypair->privkey;
396 /* Duplicate the keyid */
397 if (keypair->keyid) {
398 newpair->keyid = M_ASN1_OCTET_STRING_dup(keypair->keyid);
399 if (!newpair->keyid) {
400 /* Allocation failed */
401 crypto_keypair_free(newpair);
411 * Load a public key from a PEM-encoded x509 certificate.
412 * Returns: true on success
415 int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file)
421 if (!(bio = BIO_new_file(file, "r"))) {
422 openssl_post_errors(M_ERROR, _("Unable to open certificate file"));
426 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
429 openssl_post_errors(M_ERROR, _("Unable to read certificate from file"));
433 /* Extract the public key */
434 if (!(keypair->pubkey = X509_get_pubkey(cert))) {
435 openssl_post_errors(M_ERROR, _("Unable to extract public key from certificate"));
439 /* Extract the subjectKeyIdentifier extension field */
440 if ((keypair->keyid = openssl_cert_keyid(cert)) == NULL) {
441 Emsg0(M_ERROR, 0, _("Provided certificate does not include the required subjectKeyIdentifier extension."));
445 /* Validate the public key type (only RSA is supported) */
446 if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) {
447 Emsg1(M_ERROR, 0, _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
456 if (keypair->pubkey) {
457 EVP_PKEY_free(keypair->pubkey);
462 /* Dispatch user PEM encryption callbacks */
463 static int crypto_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
465 PEM_CB_CONTEXT *ctx = (PEM_CB_CONTEXT *) userdata;
466 return (ctx->pem_callback(buf, size, ctx->pem_userdata));
470 * Check a PEM-encoded file
471 * for the existence of a private key.
472 * Returns: true if a private key is found
475 bool crypto_keypair_has_key (const char *file) {
479 unsigned char *data = NULL;
483 if (!(bio = BIO_new_file(file, "r"))) {
484 openssl_post_errors(M_ERROR, _("Unable to open private key file"));
488 while (PEM_read_bio(bio, &name, &header, &data, &len)) {
489 /* We don't care what the data is, just that it's there */
490 OPENSSL_free(header);
494 * PEM Header Found, check for a private key
495 * Due to OpenSSL limitations, we must specifically
496 * list supported PEM private key encodings.
498 if (strcmp(name, PEM_STRING_RSA) == 0
499 || strcmp(name, PEM_STRING_DSA) == 0
500 || strcmp(name, PEM_STRING_PKCS8) == 0
501 || strcmp(name, PEM_STRING_PKCS8INF) == 0) {
513 /* Post PEM-decoding error messages, if any */
514 openssl_post_errors(M_ERROR, _("Unable to read private key from file"));
519 * Load a PEM-encoded private key.
520 * Returns: true on success
523 int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file,
524 CRYPTO_PEM_PASSWD_CB *pem_callback,
525 const void *pem_userdata)
531 if (!(bio = BIO_new_file(file, "r"))) {
532 openssl_post_errors(M_ERROR, _("Unable to open private key file"));
536 /* Set up PEM encryption callback */
538 ctx.pem_callback = pem_callback;
539 ctx.pem_userdata = pem_userdata;
541 ctx.pem_callback = crypto_default_pem_callback;
542 ctx.pem_userdata = NULL;
545 keypair->privkey = PEM_read_bio_PrivateKey(bio, NULL, crypto_pem_callback_dispatch, &ctx);
547 if (!keypair->privkey) {
548 openssl_post_errors(M_ERROR, _("Unable to read private key from file"));
556 * Free memory associated with a keypair object.
558 void crypto_keypair_free (X509_KEYPAIR *keypair)
560 if (keypair->pubkey) {
561 EVP_PKEY_free(keypair->pubkey);
563 if (keypair->privkey) {
564 EVP_PKEY_free(keypair->privkey);
566 if (keypair->keyid) {
567 M_ASN1_OCTET_STRING_free(keypair->keyid);
573 * Create a new message digest context of the specified type
574 * Returns: A pointer to a DIGEST object on success.
577 DIGEST *crypto_digest_new (crypto_digest_t type)
580 const EVP_MD *md = NULL; /* Quell invalid uninitialized warnings */
582 digest = (DIGEST *) malloc(sizeof(DIGEST));
585 /* Initialize the OpenSSL message digest context */
586 EVP_MD_CTX_init(&digest->ctx);
588 /* Determine the correct OpenSSL message digest type */
590 case CRYPTO_DIGEST_MD5:
593 case CRYPTO_DIGEST_SHA1:
597 case CRYPTO_DIGEST_SHA256:
600 case CRYPTO_DIGEST_SHA512:
605 Emsg1(M_ERROR, 0, _("Unsupported digest type: %d\n"), type);
609 /* Initialize the backing OpenSSL context */
610 if (EVP_DigestInit_ex(&digest->ctx, md, NULL) == 0) {
617 /* This should not happen, but never say never ... */
618 openssl_post_errors(M_ERROR, _("OpenSSL digest initialization failed"));
619 crypto_digest_free(digest);
624 * Hash length bytes of data into the provided digest context.
625 * Returns: true on success
628 bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) {
629 if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) {
637 * Finalize the data in digest, storing the result in dest and the result size
638 * in length. The result size can be determined with crypto_digest_size().
640 * Returns: true on success
643 bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) {
644 if (!EVP_DigestFinal(&digest->ctx, (unsigned char *) dest, (unsigned int *) length)) {
652 * Free memory associated with a digest object.
654 void crypto_digest_free (DIGEST *digest)
656 EVP_MD_CTX_cleanup(&digest->ctx);
661 * Create a new message signature context.
662 * Returns: A pointer to a SIGNATURE object on success.
665 SIGNATURE *crypto_sign_new (void)
669 sig = (SIGNATURE *) malloc(sizeof(SIGNATURE));
674 sig->sigData = SignatureData_new();
677 /* Allocation failed in OpenSSL */
682 /* Set the ASN.1 structure version number */
683 ASN1_INTEGER_set(sig->sigData->version, BACULA_ASN1_VERSION);
689 * For a given public key, find the associated SignatureInfo record
690 * and create a digest context for signature validation
691 * Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest.
692 * A crypto_error_t value on failure.
694 crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest)
696 STACK_OF(SignerInfo) *signers;
700 signers = sig->sigData->signerInfo;
702 for (i = 0; i < sk_SignerInfo_num(signers); i++) {
703 si = sk_SignerInfo_value(signers, i);
704 if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
705 /* Get the digest algorithm and allocate a digest context */
706 switch (OBJ_obj2nid(si->digestAlgorithm)) {
708 *digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
711 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
715 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
718 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
723 return CRYPTO_ERROR_INVALID_DIGEST;
726 /* Shouldn't happen */
727 if (*digest == NULL) {
728 return CRYPTO_ERROR_INVALID_DIGEST;
730 return CRYPTO_ERROR_NONE;
735 return CRYPTO_ERROR_NOSIGNER;
739 * For a given signature, public key, and digest, verify the SIGNATURE.
740 * Returns: CRYPTO_ERROR_NONE on success.
741 * A crypto_error_t value on failure.
743 crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest)
745 STACK_OF(SignerInfo) *signers;
749 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
750 const unsigned char *sigData;
752 unsigned char *sigData;
755 signers = sig->sigData->signerInfo;
757 /* Find the signer */
758 for (i = 0; i < sk_SignerInfo_num(signers); i++) {
759 si = sk_SignerInfo_value(signers, i);
760 if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
761 /* Extract the signature data */
762 sigLen = M_ASN1_STRING_length(si->signature);
763 sigData = M_ASN1_STRING_data(si->signature);
765 ok = EVP_VerifyFinal(&digest->ctx, sigData, sigLen, keypair->pubkey);
767 return CRYPTO_ERROR_NONE;
768 } else if (ok == 0) {
769 return CRYPTO_ERROR_BAD_SIGNATURE;
771 /* Shouldn't happen */
772 openssl_post_errors(M_ERROR, _("OpenSSL error occured"));
773 return CRYPTO_ERROR_INTERNAL;
778 /* Signer wasn't found. */
779 return CRYPTO_ERROR_NOSIGNER;
785 * Returns: true on success
788 int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair)
790 SignerInfo *si = NULL;
791 unsigned char *buf = NULL;
794 si = SignerInfo_new();
797 /* Allocation failed in OpenSSL */
801 /* Set the ASN.1 structure version number */
802 ASN1_INTEGER_set(si->version, BACULA_ASN1_VERSION);
804 /* Set the digest algorithm identifier */
805 switch (digest->type) {
806 case CRYPTO_DIGEST_MD5:
807 si->digestAlgorithm = OBJ_nid2obj(NID_md5);
809 case CRYPTO_DIGEST_SHA1:
810 si->digestAlgorithm = OBJ_nid2obj(NID_sha1);
813 case CRYPTO_DIGEST_SHA256:
814 si->digestAlgorithm = OBJ_nid2obj(NID_sha256);
816 case CRYPTO_DIGEST_SHA512:
817 si->digestAlgorithm = OBJ_nid2obj(NID_sha512);
821 /* This should never happen */
825 /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */
826 M_ASN1_OCTET_STRING_free(si->subjectKeyIdentifier);
827 si->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid);
829 /* Set our signature algorithm. We currently require RSA */
830 assert(EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
831 /* This is slightly evil. Reach into the MD structure and grab the key type */
832 si->signatureAlgorithm = OBJ_nid2obj(digest->ctx.digest->pkey_type);
834 /* Finalize/Sign our Digest */
835 len = EVP_PKEY_size(keypair->privkey);
836 buf = (unsigned char *) malloc(len);
837 if (!EVP_SignFinal(&digest->ctx, buf, &len, keypair->privkey)) {
838 openssl_post_errors(M_ERROR, _("Signature creation failed"));
842 /* Add the signature to the SignerInfo structure */
843 if (!M_ASN1_OCTET_STRING_set(si->signature, buf, len)) {
844 /* Allocation failed in OpenSSL */
848 /* No longer needed */
851 /* Push the new SignerInfo structure onto the stack */
852 sk_SignerInfo_push(sig->sigData->signerInfo, si);
868 * Encodes the SignatureData structure. The length argument is used to specify the
869 * size of dest. A length of 0 will cause no data to be written to dest, and the
870 * required length to be written to length. The caller can then allocate sufficient
871 * space for the output.
873 * Returns: true on success, stores the encoded data in dest, and the size in length.
876 int crypto_sign_encode(SIGNATURE *sig, void *dest, size_t *length)
879 *length = i2d_SignatureData(sig->sigData, NULL);
883 *length = i2d_SignatureData(sig->sigData, (unsigned char **) &dest);
888 * Decodes the SignatureData structure. The length argument is used to specify the
891 * Returns: SIGNATURE instance on success.
896 SIGNATURE *crypto_sign_decode(const void *sigData, size_t length)
899 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
900 const unsigned char *p = (const unsigned char *) sigData;
902 unsigned char *p = (unsigned char *) sigData;
905 sig = (SIGNATURE *) malloc(sizeof(SIGNATURE));
910 /* d2i_SignatureData modifies the supplied pointer */
911 sig->sigData = d2i_SignatureData(NULL, &p, length);
914 /* Allocation / Decoding failed in OpenSSL */
915 openssl_post_errors(M_ERROR, _("Signature decoding failed"));
923 * Free memory associated with a signature object.
925 void crypto_sign_free(SIGNATURE *sig)
927 SignatureData_free(sig->sigData);
932 * Create a new encryption session.
933 * Returns: A pointer to a CRYPTO_SESSION object on success.
936 CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
939 X509_KEYPAIR *keypair;
940 const EVP_CIPHER *ec;
944 /* Allocate our session description structures */
945 cs = (CRYPTO_SESSION *) malloc(sizeof(CRYPTO_SESSION));
950 /* Initialize required fields */
951 cs->session_key = NULL;
953 /* Allocate a CryptoData structure */
954 cs->cryptoData = CryptoData_new();
956 if (!cs->cryptoData) {
957 /* Allocation failed in OpenSSL */
962 /* Set the ASN.1 structure version number */
963 ASN1_INTEGER_set(cs->cryptoData->version, BACULA_ASN1_VERSION);
966 * Acquire a cipher instance and set the ASN.1 cipher NID
969 case CRYPTO_CIPHER_AES_128_CBC:
970 /* AES 128 bit CBC */
971 cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_128_cbc);
972 ec = EVP_aes_128_cbc();
974 case CRYPTO_CIPHER_AES_192_CBC:
975 /* AES 192 bit CBC */
976 cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_192_cbc);
977 ec = EVP_aes_192_cbc();
979 case CRYPTO_CIPHER_AES_256_CBC:
980 /* AES 256 bit CBC */
981 cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_256_cbc);
982 ec = EVP_aes_256_cbc();
984 case CRYPTO_CIPHER_BLOWFISH_CBC:
986 cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_bf_cbc);
990 Emsg0(M_ERROR, 0, _("Unsupported cipher type specified\n"));
991 crypto_session_free(cs);
995 /* Generate a symmetric session key */
996 cs->session_key_len = EVP_CIPHER_key_length(ec);
997 cs->session_key = (unsigned char *) malloc(cs->session_key_len);
998 if (RAND_bytes(cs->session_key, cs->session_key_len) <= 0) {
999 /* OpenSSL failure */
1000 crypto_session_free(cs);
1004 /* Generate an IV if possible */
1005 if ((iv_len = EVP_CIPHER_iv_length(ec))) {
1006 iv = (unsigned char *) malloc(iv_len);
1008 /* Malloc failure */
1009 crypto_session_free(cs);
1013 /* Generate random IV */
1014 if (RAND_bytes(iv, iv_len) <= 0) {
1015 /* OpenSSL failure */
1016 crypto_session_free(cs);
1021 /* Store it in our ASN.1 structure */
1022 if (!M_ASN1_OCTET_STRING_set(cs->cryptoData->iv, iv, iv_len)) {
1023 /* Allocation failed in OpenSSL */
1024 crypto_session_free(cs);
1032 * Create RecipientInfo structures for supplied
1035 foreach_alist(keypair, pubkeys) {
1037 unsigned char *ekey;
1040 ri = RecipientInfo_new();
1042 /* Allocation failed in OpenSSL */
1043 crypto_session_free(cs);
1047 /* Set the ASN.1 structure version number */
1048 ASN1_INTEGER_set(ri->version, BACULA_ASN1_VERSION);
1050 /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */
1051 M_ASN1_OCTET_STRING_free(ri->subjectKeyIdentifier);
1052 ri->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid);
1054 /* Set our key encryption algorithm. We currently require RSA */
1055 assert(keypair->pubkey && EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
1056 ri->keyEncryptionAlgorithm = OBJ_nid2obj(NID_rsaEncryption);
1058 /* Encrypt the session key */
1059 ekey = (unsigned char *) malloc(EVP_PKEY_size(keypair->pubkey));
1061 RecipientInfo_free(ri);
1062 crypto_session_free(cs);
1066 if ((ekey_len = EVP_PKEY_encrypt(ekey, cs->session_key, cs->session_key_len, keypair->pubkey)) <= 0) {
1067 /* OpenSSL failure */
1068 RecipientInfo_free(ri);
1069 crypto_session_free(cs);
1074 /* Store it in our ASN.1 structure */
1075 if (!M_ASN1_OCTET_STRING_set(ri->encryptedKey, ekey, ekey_len)) {
1076 /* Allocation failed in OpenSSL */
1077 RecipientInfo_free(ri);
1078 crypto_session_free(cs);
1083 /* Free the encrypted key buffer */
1086 /* Push the new RecipientInfo structure onto the stack */
1087 sk_RecipientInfo_push(cs->cryptoData->recipientInfo, ri);
1094 * Encodes the CryptoData structure. The length argument is used to specify the
1095 * size of dest. A length of 0 will cause no data to be written to dest, and the
1096 * required length to be written to length. The caller can then allocate sufficient
1097 * space for the output.
1099 * Returns: true on success, stores the encoded data in dest, and the size in length.
1102 bool crypto_session_encode(CRYPTO_SESSION *cs, void *dest, size_t *length)
1105 *length = i2d_CryptoData(cs->cryptoData, NULL);
1109 *length = i2d_CryptoData(cs->cryptoData, (unsigned char **) &dest);
1114 * Decodes the CryptoData structure. The length argument is
1115 * used to specify the size of data.
1117 * Returns: CRYPTO_SESSION instance on success.
1119 * Returns: CRYPTO_ERROR_NONE and a pointer to a newly allocated CRYPTO_SESSION structure in *session on success.
1120 * A crypto_error_t value on failure.
1122 crypto_error_t crypto_session_decode(const void *data, size_t length, alist *keypairs, CRYPTO_SESSION **session)
1125 X509_KEYPAIR *keypair;
1126 STACK_OF(RecipientInfo) *recipients;
1127 crypto_error_t retval = CRYPTO_ERROR_NONE;
1128 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
1129 const unsigned char *p = (const unsigned char *) data;
1131 unsigned char *p = (unsigned char *) data;
1134 cs = (CRYPTO_SESSION *) malloc(sizeof(CRYPTO_SESSION));
1136 return CRYPTO_ERROR_INTERNAL;
1139 /* d2i_CryptoData modifies the supplied pointer */
1140 cs->cryptoData = d2i_CryptoData(NULL, &p, length);
1142 if (!cs->cryptoData) {
1143 /* Allocation / Decoding failed in OpenSSL */
1144 openssl_post_errors(M_ERROR, _("CryptoData decoding failed"));
1145 retval = CRYPTO_ERROR_INTERNAL;
1149 recipients = cs->cryptoData->recipientInfo;
1152 * Find a matching RecipientInfo structure for a supplied
1155 foreach_alist(keypair, keypairs) {
1159 /* Private key available? */
1160 if (keypair->privkey == NULL) {
1164 for (i = 0; i < sk_RecipientInfo_num(recipients); i++) {
1165 ri = sk_RecipientInfo_value(recipients, i);
1167 /* Match against the subjectKeyIdentifier */
1168 if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, ri->subjectKeyIdentifier) == 0) {
1169 /* Match found, extract symmetric encryption session data */
1171 /* RSA is required. */
1172 assert(EVP_PKEY_type(keypair->privkey->type) == EVP_PKEY_RSA);
1174 /* If we recieve a RecipientInfo structure that does not use
1175 * RSA, return an error */
1176 if (OBJ_obj2nid(ri->keyEncryptionAlgorithm) != NID_rsaEncryption) {
1177 retval = CRYPTO_ERROR_INVALID_CRYPTO;
1181 /* Decrypt the session key */
1182 /* Allocate sufficient space for the largest possible decrypted data */
1183 cs->session_key = (unsigned char *) malloc(EVP_PKEY_size(keypair->privkey));
1184 cs->session_key_len = EVP_PKEY_decrypt(cs->session_key, M_ASN1_STRING_data(ri->encryptedKey),
1185 M_ASN1_STRING_length(ri->encryptedKey), keypair->privkey);
1187 if (cs->session_key_len <= 0) {
1188 openssl_post_errors(M_ERROR, _("Failure decrypting the session key"));
1189 retval = CRYPTO_ERROR_DECRYPTION;
1193 /* Session key successfully extracted, return the CRYPTO_SESSION structure */
1195 return CRYPTO_ERROR_NONE;
1200 /* No matching recipient found */
1201 return CRYPTO_ERROR_NORECIPIENT;
1204 crypto_session_free(cs);
1209 * Free memory associated with a crypto session object.
1211 void crypto_session_free (CRYPTO_SESSION *cs)
1213 if (cs->cryptoData) {
1214 CryptoData_free(cs->cryptoData);
1216 if (cs->session_key){
1217 free(cs->session_key);
1223 * Create a new crypto cipher context with the specified session object
1224 * Returns: A pointer to a CIPHER_CONTEXT object on success. The cipher block size is returned in blocksize.
1227 CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, size_t *blocksize)
1229 CIPHER_CONTEXT *cipher_ctx;
1230 const EVP_CIPHER *ec;
1232 cipher_ctx = (CIPHER_CONTEXT *) malloc(sizeof(CIPHER_CONTEXT));
1238 * Acquire a cipher instance for the given ASN.1 cipher NID
1240 if ((ec = EVP_get_cipherbyobj(cs->cryptoData->contentEncryptionAlgorithm)) == NULL) {
1241 Emsg1(M_ERROR, 0, _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm));
1242 crypto_cipher_free(cipher_ctx);
1246 /* Initialize the OpenSSL cipher context */
1247 EVP_CIPHER_CTX_init(&cipher_ctx->ctx);
1249 /* Initialize for encryption */
1250 if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 1)) {
1251 openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed"));
1255 /* Initialize for decryption */
1256 if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 0)) {
1257 openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed"));
1262 /* Set the key size */
1263 if (!EVP_CIPHER_CTX_set_key_length(&cipher_ctx->ctx, cs->session_key_len)) {
1264 openssl_post_errors(M_ERROR, _("Encryption session provided an invalid symmetric key"));
1268 /* Validate the IV length */
1269 if (EVP_CIPHER_iv_length(ec) != M_ASN1_STRING_length(cs->cryptoData->iv)) {
1270 openssl_post_errors(M_ERROR, _("Encryption session provided an invalid IV"));
1274 /* Add the key and IV to the cipher context */
1275 if (!EVP_CipherInit_ex(&cipher_ctx->ctx, NULL, NULL, cs->session_key, M_ASN1_STRING_data(cs->cryptoData->iv), -1)) {
1276 openssl_post_errors(M_ERROR, _("OpenSSL cipher context key/IV initialization failed"));
1280 *blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx->ctx);
1284 crypto_cipher_free(cipher_ctx);
1290 * Encrypt/Decrypt length bytes of data using the provided cipher context
1291 * Returns: true on success, number of bytes output in written
1294 bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const void *data, size_t length, const void *dest, size_t *written) {
1295 if (!EVP_CipherUpdate(&cipher_ctx->ctx, (unsigned char *) dest, (int *) written, (const unsigned char *) data, length)) {
1296 /* This really shouldn't fail */
1304 * Finalize the cipher context, writing any remaining data and necessary padding
1305 * to dest, and the size in written.
1306 * The result size will either be one block of data or zero.
1308 * Returns: true on success
1311 bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, void *dest, size_t *written) {
1312 if (!EVP_CipherFinal_ex(&cipher_ctx->ctx, (unsigned char *) dest, (int *) written)) {
1313 /* This really shouldn't fail */
1322 * Free memory associated with a cipher context.
1324 void crypto_cipher_free (CIPHER_CONTEXT *cipher_ctx)
1326 EVP_CIPHER_CTX_cleanup(&cipher_ctx->ctx);
1332 * Perform global initialization of OpenSSL
1333 * This function is not thread safe.
1334 * Returns: 0 on success
1337 int init_crypto (void)
1341 if ((stat = openssl_init_threads()) != 0) {
1342 Emsg1(M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), strerror(stat));
1345 /* Load libssl and libcrypto human-readable error strings */
1346 SSL_load_error_strings();
1348 /* Register OpenSSL ciphers */
1351 if (!openssl_seed_prng()) {
1352 Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
1355 crypto_initialized = true;
1361 * Perform global cleanup of OpenSSL
1362 * All cryptographic operations must be completed before calling this function.
1363 * This function is not thread safe.
1364 * Returns: 0 on success
1367 int cleanup_crypto (void)
1370 * Ensure that we've actually been initialized; Doing this here decreases the
1371 * complexity of client's termination/cleanup code.
1373 if (!crypto_initialized) {
1377 if (!openssl_save_prng()) {
1378 Emsg0(M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
1381 openssl_cleanup_threads();
1383 /* Free libssl and libcrypto error strings */
1386 /* Free memory used by PRNG */
1389 crypto_initialized = false;
1395 #else /* HAVE_OPENSSL */
1396 # error No encryption library available
1397 #endif /* HAVE_OPENSSL */
1399 #else /* HAVE_CRYPTO */
1402 * Cryptography Support Disabled
1405 /* Message Digest Structure */
1407 crypto_digest_t type;
1414 /* Dummy Signature Structure */
1418 DIGEST *crypto_digest_new (crypto_digest_t type)
1422 digest = (DIGEST *) malloc(sizeof(DIGEST));
1423 digest->type = type;
1426 case CRYPTO_DIGEST_MD5:
1427 MD5Init(&digest->md5);
1429 case CRYPTO_DIGEST_SHA1:
1430 SHA1Init(&digest->sha1);
1433 Emsg0(M_ERROR, 0, _("Unsupported digest type specified\n"));
1441 bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) {
1442 switch (digest->type) {
1443 case CRYPTO_DIGEST_MD5:
1444 /* Doesn't return anything ... */
1445 MD5Update(&digest->md5, (unsigned char *) data, length);
1447 case CRYPTO_DIGEST_SHA1:
1449 if ((ret = SHA1Update(&digest->sha1, (const u_int8_t *) data, length)) == shaSuccess) {
1452 Emsg1(M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
1461 bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) {
1463 switch (digest->type) {
1464 case CRYPTO_DIGEST_MD5:
1465 /* Guard against programmer error by either the API client or
1466 * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */
1467 assert(*length >= CRYPTO_DIGEST_MD5_SIZE);
1468 *length = CRYPTO_DIGEST_MD5_SIZE;
1469 /* Doesn't return anything ... */
1470 MD5Final((unsigned char *) dest, &digest->md5);
1472 case CRYPTO_DIGEST_SHA1:
1473 /* Guard against programmer error by either the API client or
1474 * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */
1475 assert(*length >= CRYPTO_DIGEST_SHA1_SIZE);
1476 *length = CRYPTO_DIGEST_SHA1_SIZE;
1477 if (SHA1Final(&digest->sha1, (u_int8_t *) dest) == shaSuccess) {
1490 void crypto_digest_free (DIGEST *digest)
1495 /* Dummy routines */
1496 int init_crypto (void) { return 0; }
1497 int cleanup_crypto (void) { return 0; }
1499 SIGNATURE *crypto_sign_new (void) { return NULL; }
1501 crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; }
1502 crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; }
1504 int crypto_sign_add_signer (SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; }
1505 int crypto_sign_encode (SIGNATURE *sig, void *dest, size_t *length) { return false; }
1507 SIGNATURE *crypto_sign_decode (const void *sigData, size_t length) { return NULL; }
1508 void crypto_sign_free (SIGNATURE *sig) { }
1511 X509_KEYPAIR *crypto_keypair_new (void) { return NULL; }
1512 X509_KEYPAIR *crypto_keypair_dup (X509_KEYPAIR *keypair) { return NULL; }
1513 int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file) { return false; }
1514 bool crypto_keypair_has_key (const char *file) { return false; }
1515 int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { return false; }
1516 void crypto_keypair_free (X509_KEYPAIR *keypair) { }
1518 CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) { return NULL; }
1519 void crypto_session_free (CRYPTO_SESSION *cs) { }
1520 bool crypto_session_encode (CRYPTO_SESSION *cs, void *dest, size_t *length) { return false; }
1521 crypto_error_t crypto_session_decode (const void *data, size_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; }
1523 CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, size_t *blocksize) { return NULL; }
1524 bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const void *data, size_t length, const void *dest, size_t *written) { return false; }
1525 bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, void *dest, size_t *written) { return false; }
1526 void crypto_cipher_free (CIPHER_CONTEXT *cipher_ctx) { }
1528 #endif /* HAVE_CRYPTO */
1533 * Default PEM encryption passphrase callback.
1534 * Returns an empty password.
1536 int crypto_default_pem_callback(char *buf, int size, const void *userdata)
1538 bstrncpy(buf, "", size);
1539 return (strlen(buf));
1543 * Returns the ASCII name of the digest type.
1544 * Returns: ASCII name of digest type.
1546 const char *crypto_digest_name (DIGEST *digest) {
1547 switch (digest->type) {
1548 case CRYPTO_DIGEST_MD5:
1550 case CRYPTO_DIGEST_SHA1:
1552 case CRYPTO_DIGEST_SHA256:
1554 case CRYPTO_DIGEST_SHA512:
1556 case CRYPTO_DIGEST_NONE:
1559 return "Invalid Digest Type";
1565 * Given a stream type, returns the associated
1566 * crypto_digest_t value.
1568 crypto_digest_t crypto_digest_stream_type (int stream) {
1570 case STREAM_MD5_DIGEST:
1571 return CRYPTO_DIGEST_MD5;
1572 case STREAM_SHA1_DIGEST:
1573 return CRYPTO_DIGEST_SHA1;
1574 case STREAM_SHA256_DIGEST:
1575 return CRYPTO_DIGEST_SHA256;
1576 case STREAM_SHA512_DIGEST:
1577 return CRYPTO_DIGEST_SHA512;
1579 return CRYPTO_DIGEST_NONE;
1584 * * Given a crypto_error_t value, return the associated
1587 const char *crypto_strerror(crypto_error_t error) {
1589 case CRYPTO_ERROR_NONE:
1591 case CRYPTO_ERROR_NOSIGNER:
1592 return "Signer not found";
1593 case CRYPTO_ERROR_NORECIPIENT:
1594 return "Recipient not found";
1595 case CRYPTO_ERROR_INVALID_DIGEST:
1596 return "Unsupported digest algorithm";
1597 case CRYPTO_ERROR_INVALID_CRYPTO:
1598 return "Unsupported encryption algorithm";
1599 case CRYPTO_ERROR_BAD_SIGNATURE:
1600 return "Signature is invalid";
1601 case CRYPTO_ERROR_DECRYPTION:
1602 return "Decryption error";
1603 case CRYPTO_ERROR_INTERNAL:
1604 /* This shouldn't happen */
1605 return "Internal error";
1607 return "Unknown error";