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 * recipientInfo RecipientInfo
80 * SignerInfo ::= SET OF SignerInfo
81 * RecipientInfo ::= SET OF RecipientInfo
83 * Version ::= INTEGER { v0(0) }
85 * SignerInfo ::= SEQUENCE {
87 * subjectKeyIdentifier SubjectKeyIdentifier,
88 * digestAlgorithm DigestAlgorithmIdentifier,
89 * signatureAlgorithm SignatureAlgorithmIdentifier,
90 * signature SignatureValue }
92 * RecipientInfo ::= SEQUENCE {
94 * subjectKeyIdentifier SubjectKeyIdentifier
95 * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier
96 * encryptedKey EncryptedKey
99 * SubjectKeyIdentifier ::= OCTET STRING
101 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
103 * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
105 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
107 * SignatureValue ::= OCTET STRING
109 * EncryptedKey ::= OCTET STRING
111 * AlgorithmIdentifier ::= OBJECT IDENTIFIER
116 #ifdef HAVE_CRYPTO /* Is encryption enabled? */
117 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
119 /* Are we initialized? */
120 static int crypto_initialized = false;
122 /* ASN.1 Declarations */
123 #define BACULA_ASN1_VERSION 0
126 ASN1_INTEGER *version;
127 ASN1_OCTET_STRING *subjectKeyIdentifier;
128 ASN1_OBJECT *digestAlgorithm;
129 ASN1_OBJECT *signatureAlgorithm;
130 ASN1_OCTET_STRING *signature;
134 ASN1_INTEGER *version;
135 ASN1_OCTET_STRING *subjectKeyIdentifier;
136 ASN1_OBJECT *keyEncryptionAlgorithm;
137 ASN1_OCTET_STRING *encryptedKey;
140 ASN1_SEQUENCE(SignerInfo) = {
141 ASN1_SIMPLE(SignerInfo, version, ASN1_INTEGER),
142 ASN1_SIMPLE(SignerInfo, subjectKeyIdentifier, ASN1_OCTET_STRING),
143 ASN1_SIMPLE(SignerInfo, digestAlgorithm, ASN1_OBJECT),
144 ASN1_SIMPLE(SignerInfo, signatureAlgorithm, ASN1_OBJECT),
145 ASN1_SIMPLE(SignerInfo, signature, ASN1_OCTET_STRING)
146 } ASN1_SEQUENCE_END(SignerInfo);
148 ASN1_SEQUENCE(RecipientInfo) = {
149 ASN1_SIMPLE(RecipientInfo, version, ASN1_INTEGER),
150 ASN1_SIMPLE(RecipientInfo, subjectKeyIdentifier, ASN1_OCTET_STRING),
151 ASN1_SIMPLE(RecipientInfo, keyEncryptionAlgorithm, ASN1_OBJECT),
152 ASN1_SIMPLE(RecipientInfo, encryptedKey, ASN1_OCTET_STRING),
153 } ASN1_SEQUENCE_END(RecipientInfo);
156 ASN1_INTEGER *version;
157 STACK_OF(SignerInfo) *signerInfo;
161 ASN1_INTEGER *version;
162 ASN1_OBJECT *contentEncryptionAlgorithm;
163 STACK_OF(RecipientInfo) *recipientInfo;
166 ASN1_SEQUENCE(SignatureData) = {
167 ASN1_SIMPLE(SignatureData, version, ASN1_INTEGER),
168 ASN1_SET_OF(SignatureData, signerInfo, SignerInfo),
169 } ASN1_SEQUENCE_END(SignatureData);
171 ASN1_SEQUENCE(CryptoData) = {
172 ASN1_SIMPLE(CryptoData, version, ASN1_INTEGER),
173 ASN1_SET_OF(CryptoData, recipientInfo, RecipientInfo)
174 } ASN1_SEQUENCE_END(CryptoData);
176 IMPLEMENT_ASN1_FUNCTIONS(SignerInfo)
177 IMPLEMENT_ASN1_FUNCTIONS(SignatureData)
178 IMPLEMENT_ASN1_FUNCTIONS(CryptoData)
179 IMPLEMENT_STACK_OF(SignerInfo)
180 IMPLEMENT_STACK_OF(RecipientInfo)
183 * SignerInfo and RecipientInfo stack macros, generated by OpenSSL's util/mkstack.pl.
185 #define sk_SignerInfo_new(st) SKM_sk_new(SignerInfo, (st))
186 #define sk_SignerInfo_new_null() SKM_sk_new_null(SignerInfo)
187 #define sk_SignerInfo_free(st) SKM_sk_free(SignerInfo, (st))
188 #define sk_SignerInfo_num(st) SKM_sk_num(SignerInfo, (st))
189 #define sk_SignerInfo_value(st, i) SKM_sk_value(SignerInfo, (st), (i))
190 #define sk_SignerInfo_set(st, i, val) SKM_sk_set(SignerInfo, (st), (i), (val))
191 #define sk_SignerInfo_zero(st) SKM_sk_zero(SignerInfo, (st))
192 #define sk_SignerInfo_push(st, val) SKM_sk_push(SignerInfo, (st), (val))
193 #define sk_SignerInfo_unshift(st, val) SKM_sk_unshift(SignerInfo, (st), (val))
194 #define sk_SignerInfo_find(st, val) SKM_sk_find(SignerInfo, (st), (val))
195 #define sk_SignerInfo_delete(st, i) SKM_sk_delete(SignerInfo, (st), (i))
196 #define sk_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(SignerInfo, (st), (ptr))
197 #define sk_SignerInfo_insert(st, val, i) SKM_sk_insert(SignerInfo, (st), (val), (i))
198 #define sk_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SignerInfo, (st), (cmp))
199 #define sk_SignerInfo_dup(st) SKM_sk_dup(SignerInfo, st)
200 #define sk_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(SignerInfo, (st), (free_func))
201 #define sk_SignerInfo_shift(st) SKM_sk_shift(SignerInfo, (st))
202 #define sk_SignerInfo_pop(st) SKM_sk_pop(SignerInfo, (st))
203 #define sk_SignerInfo_sort(st) SKM_sk_sort(SignerInfo, (st))
204 #define sk_SignerInfo_is_sorted(st) SKM_sk_is_sorted(SignerInfo, (st))
206 #define d2i_ASN1_SET_OF_SignerInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
207 SKM_ASN1_SET_OF_d2i(SignerInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
208 #define i2d_ASN1_SET_OF_SignerInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
209 SKM_ASN1_SET_OF_i2d(SignerInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
210 #define ASN1_seq_pack_SignerInfo(st, i2d_func, buf, len) \
211 SKM_ASN1_seq_pack(SignerInfo, (st), (i2d_func), (buf), (len))
212 #define ASN1_seq_unpack_SignerInfo(buf, len, d2i_func, free_func) \
213 SKM_ASN1_seq_unpack(SignerInfo, (buf), (len), (d2i_func), (free_func))
215 #define sk_RecipientInfo_new(st) SKM_sk_new(RecipientInfo, (st))
216 #define sk_RecipientInfo_new_null() SKM_sk_new_null(RecipientInfo)
217 #define sk_RecipientInfo_free(st) SKM_sk_free(RecipientInfo, (st))
218 #define sk_RecipientInfo_num(st) SKM_sk_num(RecipientInfo, (st))
219 #define sk_RecipientInfo_value(st, i) SKM_sk_value(RecipientInfo, (st), (i))
220 #define sk_RecipientInfo_set(st, i, val) SKM_sk_set(RecipientInfo, (st), (i), (val))
221 #define sk_RecipientInfo_zero(st) SKM_sk_zero(RecipientInfo, (st))
222 #define sk_RecipientInfo_push(st, val) SKM_sk_push(RecipientInfo, (st), (val))
223 #define sk_RecipientInfo_unshift(st, val) SKM_sk_unshift(RecipientInfo, (st), (val))
224 #define sk_RecipientInfo_find(st, val) SKM_sk_find(RecipientInfo, (st), (val))
225 #define sk_RecipientInfo_delete(st, i) SKM_sk_delete(RecipientInfo, (st), (i))
226 #define sk_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(RecipientInfo, (st), (ptr))
227 #define sk_RecipientInfo_insert(st, val, i) SKM_sk_insert(RecipientInfo, (st), (val), (i))
228 #define sk_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(RecipientInfo, (st), (cmp))
229 #define sk_RecipientInfo_dup(st) SKM_sk_dup(RecipientInfo, st)
230 #define sk_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(RecipientInfo, (st), (free_func))
231 #define sk_RecipientInfo_shift(st) SKM_sk_shift(RecipientInfo, (st))
232 #define sk_RecipientInfo_pop(st) SKM_sk_pop(RecipientInfo, (st))
233 #define sk_RecipientInfo_sort(st) SKM_sk_sort(RecipientInfo, (st))
234 #define sk_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(RecipientInfo, (st))
236 #define d2i_ASN1_SET_OF_RecipientInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
237 SKM_ASN1_SET_OF_d2i(RecipientInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
238 #define i2d_ASN1_SET_OF_RecipientInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
239 SKM_ASN1_SET_OF_i2d(RecipientInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
240 #define ASN1_seq_pack_RecipientInfo(st, i2d_func, buf, len) \
241 SKM_ASN1_seq_pack(RecipientInfo, (st), (i2d_func), (buf), (len))
242 #define ASN1_seq_unpack_RecipientInfo(buf, len, d2i_func, free_func) \
243 SKM_ASN1_seq_unpack(RecipientInfo, (buf), (len), (d2i_func), (free_func))
244 /* End of util/mkstack.pl block */
246 /* X509 Public/Private Key Pair Structure */
247 struct X509_Keypair {
248 ASN1_OCTET_STRING *keyid;
253 /* Message Digest Structure */
255 crypto_digest_t type;
259 /* Message Signature Structure */
261 SignatureData *sigData;
264 /* PEM Password Dispatch Context */
265 typedef struct PEM_CB_Context {
266 CRYPTO_PEM_PASSWD_CB *pem_callback;
267 const void *pem_userdata;
271 * Extract subjectKeyIdentifier from x509 certificate.
272 * Returns: On success, an ASN1_OCTET_STRING that must be freed via M_ASN1_OCTET_STRING_free().
275 static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert){
277 X509V3_EXT_METHOD *method;
278 ASN1_OCTET_STRING *keyid;
280 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
281 const unsigned char *ext_value_data;
283 unsigned char *ext_value_data;
287 /* Find the index to the subjectKeyIdentifier extension */
288 i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
294 /* Grab the extension */
295 ext = X509_get_ext(cert, i);
297 /* Get x509 extension method structure */
298 if (!(method = X509V3_EXT_get(ext))) {
302 ext_value_data = ext->value->data;
304 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
308 /* Decode ASN1 item in data */
309 keyid = (ASN1_OCTET_STRING *) ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
310 ASN1_ITEM_ptr(method->it));
314 /* Decode ASN1 item in data */
315 keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
319 keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
326 * Create a new keypair object.
327 * Returns: A pointer to a X509 KEYPAIR object on success.
330 X509_KEYPAIR *crypto_keypair_new (void) {
331 X509_KEYPAIR *keypair;
333 /* Allocate our keypair structure */
334 keypair = (X509_KEYPAIR *) malloc(sizeof(X509_KEYPAIR));
339 /* Initialize our keypair structure */
340 keypair->keyid = NULL;
341 keypair->pubkey = NULL;
342 keypair->privkey = NULL;
348 * Load a public key from a PEM-encoded x509 certificate.
349 * Returns: true on success
352 int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file)
358 if (!(bio = BIO_new_file(file, "r"))) {
359 openssl_post_errors(M_ERROR, _("Unable to open certificate file"));
363 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
366 openssl_post_errors(M_ERROR, _("Unable to read certificate from file"));
370 /* Extract the public key */
371 if (!(keypair->pubkey = X509_get_pubkey(cert))) {
372 openssl_post_errors(M_ERROR, _("Unable to extract public key from certificate"));
376 /* Extract the subjectKeyIdentifier extension field */
377 if ((keypair->keyid = openssl_cert_keyid(cert)) == NULL) {
378 Emsg0(M_ERROR, 0, _("Provided certificate does not include the required subjectKeyIdentifier extension."));
382 /* Validate the public key type (only RSA is supported) */
383 if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) {
384 Emsg1(M_ERROR, 0, _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
392 if (keypair->pubkey) {
393 EVP_PKEY_free(keypair->pubkey);
398 /* Dispatch user PEM encryption callbacks */
399 static int crypto_pem_callback_dispatch (char *buf, int size, int rwflag, void *userdata)
401 PEM_CB_CONTEXT *ctx = (PEM_CB_CONTEXT *) userdata;
402 return (ctx->pem_callback(buf, size, ctx->pem_userdata));
406 * Load a PEM-encoded private key.
407 * Returns: true on success
410 int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file,
411 CRYPTO_PEM_PASSWD_CB *pem_callback,
412 const void *pem_userdata)
418 if (!(bio = BIO_new_file(file, "r"))) {
419 openssl_post_errors(M_ERROR, _("Unable to open private key file"));
423 /* Set up PEM encryption callback */
425 ctx.pem_callback = pem_callback;
426 ctx.pem_userdata = pem_userdata;
428 ctx.pem_callback = crypto_default_pem_callback;
429 ctx.pem_userdata = NULL;
432 keypair->privkey = PEM_read_bio_PrivateKey(bio, NULL, crypto_pem_callback_dispatch, &ctx);
434 if (!keypair->privkey) {
435 openssl_post_errors(M_ERROR, _("Unable to read private key from file"));
443 * Free memory associated with a keypair object.
445 void crypto_keypair_free (X509_KEYPAIR *keypair)
447 if (keypair->pubkey) {
448 EVP_PKEY_free(keypair->pubkey);
450 if (keypair->privkey) {
451 EVP_PKEY_free(keypair->privkey);
453 if (keypair->keyid) {
454 M_ASN1_OCTET_STRING_free(keypair->keyid);
460 * Create a new message digest context of the specified type
461 * Returns: A pointer to a DIGEST object on success.
464 DIGEST *crypto_digest_new (crypto_digest_t type)
467 const EVP_MD *md = NULL; /* Quell invalid uninitialized warnings */
469 digest = (DIGEST *) malloc(sizeof(DIGEST));
472 /* Initialize the OpenSSL message digest context */
473 EVP_MD_CTX_init(&digest->ctx);
475 /* Determine the correct OpenSSL message digest type */
477 case CRYPTO_DIGEST_MD5:
480 case CRYPTO_DIGEST_SHA1:
484 case CRYPTO_DIGEST_SHA256:
487 case CRYPTO_DIGEST_SHA512:
492 Emsg1(M_ERROR, 0, _("Unsupported digest type: %d\n"), type);
496 /* Initialize the backing OpenSSL context */
497 if (EVP_DigestInit_ex(&digest->ctx, md, NULL) == 0) {
504 /* This should not happen, but never say never ... */
505 openssl_post_errors(M_ERROR, _("OpenSSL digest initialization failed"));
506 crypto_digest_free(digest);
511 * Hash length bytes of data into the provided digest context.
512 * Returns: true on success
515 int crypto_digest_update (DIGEST *digest, const void *data, size_t length) {
516 if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) {
524 * Finalize the data in digest, storing the result in dest and the result size
525 * in length. The result size can be determined with crypto_digest_size().
527 * Returns: true on success
530 int crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) {
531 if (!EVP_DigestFinal(&digest->ctx, (unsigned char *) dest, length)) {
539 * Free memory associated with a digest object.
541 void crypto_digest_free (DIGEST *digest)
543 EVP_MD_CTX_cleanup(&digest->ctx);
548 * Create a new message signature context.
549 * Returns: A pointer to a SIGNATURE object on success.
552 SIGNATURE *crypto_sign_new (void)
556 sig = (SIGNATURE *) malloc(sizeof(SIGNATURE));
561 sig->sigData = SignatureData_new();
564 /* Allocation failed in OpenSSL */
569 /* Set the ASN.1 structure version number */
570 ASN1_INTEGER_set(sig->sigData->version, BACULA_ASN1_VERSION);
576 * For a given public key, find the associated SignatureInfo record
577 * and create a digest context for signature validation
578 * Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest.
579 * A crypto_error_t value on failure.
581 crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest)
583 STACK_OF(SignerInfo) *signers;
587 signers = sig->sigData->signerInfo;
589 for (i = 0; i < sk_SignerInfo_num(signers); i++) {
590 si = sk_SignerInfo_value(signers, i);
591 if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
592 /* Get the digest algorithm and allocate a digest context */
593 switch (OBJ_obj2nid(si->digestAlgorithm)) {
595 *digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
598 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
602 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
605 *digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
610 return CRYPTO_ERROR_INVALID_DIGEST;
613 /* Shouldn't happen */
614 if (*digest == NULL) {
615 return CRYPTO_ERROR_INVALID_DIGEST;
617 return CRYPTO_ERROR_NONE;
622 return CRYPTO_ERROR_NOSIGNER;
626 * For a given signature, public key, and digest, verify the SIGNATURE.
627 * Returns: CRYPTO_ERROR_NONE on success.
628 * A crypto_error_t value on failure.
630 crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest)
632 STACK_OF(SignerInfo) *signers;
636 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
637 const unsigned char *sigData;
639 unsigned char *sigData;
642 signers = sig->sigData->signerInfo;
644 /* Find the signer */
645 for (i = 0; i < sk_SignerInfo_num(signers); i++) {
646 si = sk_SignerInfo_value(signers, i);
647 if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
648 /* Extract the signature data */
649 sigLen = M_ASN1_STRING_length(si->signature);
650 sigData = M_ASN1_STRING_data(si->signature);
652 ok = EVP_VerifyFinal(&digest->ctx, sigData, sigLen, keypair->pubkey);
654 return CRYPTO_ERROR_NONE;
655 } else if (ok == 0) {
656 return CRYPTO_ERROR_BAD_SIGNATURE;
658 /* Shouldn't happen */
659 openssl_post_errors(M_ERROR, _("OpenSSL error occured"));
660 return CRYPTO_ERROR_INTERNAL;
665 /* Signer wasn't found. */
666 return CRYPTO_ERROR_NOSIGNER;
672 * Returns: true on success
675 int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair)
677 SignerInfo *si = NULL;
678 unsigned char *buf = NULL;
681 si = SignerInfo_new();
684 /* Allocation failed in OpenSSL */
688 /* Set the ASN.1 structure version number */
689 ASN1_INTEGER_set(si->version, BACULA_ASN1_VERSION);
691 /* Set the digest algorithm identifier */
692 switch (digest->type) {
693 case CRYPTO_DIGEST_MD5:
694 si->digestAlgorithm = OBJ_nid2obj(NID_md5);
696 case CRYPTO_DIGEST_SHA1:
697 si->digestAlgorithm = OBJ_nid2obj(NID_sha1);
700 case CRYPTO_DIGEST_SHA256:
701 si->digestAlgorithm = OBJ_nid2obj(NID_sha256);
703 case CRYPTO_DIGEST_SHA512:
704 si->digestAlgorithm = OBJ_nid2obj(NID_sha512);
708 /* This should never happen */
712 /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */
713 M_ASN1_OCTET_STRING_free(si->subjectKeyIdentifier);
714 si->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid);
716 /* Set our signature algorithm. We currently require RSA */
717 assert(EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
718 /* This is slightly evil. Reach into the MD structure and grab the key type */
719 si->signatureAlgorithm = OBJ_nid2obj(digest->ctx.digest->pkey_type);
721 /* Finalize/Sign our Digest */
722 len = EVP_PKEY_size(keypair->privkey);
723 buf = (unsigned char *) malloc(len);
724 if (!EVP_SignFinal(&digest->ctx, buf, &len, keypair->privkey)) {
725 openssl_post_errors(M_ERROR, _("Signature creation failed"));
729 /* Add the signature to the SignerInfo structure */
730 if (!M_ASN1_OCTET_STRING_set(si->signature, buf, len)) {
731 /* Allocation failed in OpenSSL */
735 /* No longer needed */
738 /* Push the new SignerInfo structure onto the stack */
739 sk_SignerInfo_push(sig->sigData->signerInfo, si);
755 * Encodes the SignatureData structure. The length argument is used to specify the
756 * size of dest. A length of 0 will cause no data to be written to dest, and the
757 * required length to be written to length. The caller can then allocate sufficient
758 * space for the output.
760 * Returns: true on success, stores the encoded data in dest, and the size in length.
763 int crypto_sign_encode(SIGNATURE *sig, void *dest, size_t *length)
766 *length = i2d_SignatureData(sig->sigData, NULL);
770 *length = i2d_SignatureData(sig->sigData, (unsigned char **) &dest);
775 * Decodes the SignatureData structure. The length argument is used to specify the
778 * Returns: SIGNATURE instance on success.
783 SIGNATURE *crypto_sign_decode(const void *sigData, size_t length)
786 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
787 const unsigned char *p = (const unsigned char *) sigData;
789 unsigned char *p = (unsigned char *) sigData;
792 sig = (SIGNATURE *) malloc(sizeof(SIGNATURE));
797 /* d2i_SignatureData modifies the supplied pointer */
798 sig->sigData = d2i_SignatureData(NULL, &p, length);
801 /* Allocation / Decoding failed in OpenSSL */
802 openssl_post_errors(M_ERROR, _("Signature decoding failed"));
810 * Free memory associated with a signature object.
812 void crypto_sign_free(SIGNATURE *sig)
814 SignatureData_free(sig->sigData);
819 * Perform global initialization of OpenSSL
820 * This function is not thread safe.
821 * Returns: 0 on success
824 int init_crypto (void)
828 if ((stat = openssl_init_threads()) != 0) {
829 Emsg1(M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), strerror(stat));
832 /* Load libssl and libcrypto human-readable error strings */
833 SSL_load_error_strings();
835 /* Register OpenSSL ciphers */
838 if (!openssl_seed_prng()) {
839 Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
842 crypto_initialized = true;
848 * Perform global cleanup of OpenSSL
849 * All cryptographic operations must be completed before calling this function.
850 * This function is not thread safe.
851 * Returns: 0 on success
854 int cleanup_crypto (void)
857 * Ensure that we've actually been initialized; Doing this here decreases the
858 * complexity of client's termination/cleanup code.
860 if (!crypto_initialized) {
864 if (!openssl_save_prng()) {
865 Emsg0(M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
868 openssl_cleanup_threads();
870 /* Free libssl and libcrypto error strings */
873 /* Free memory used by PRNG */
876 crypto_initialized = false;
882 #else /* HAVE_OPENSSL */
883 # error No encryption library available
884 #endif /* HAVE_OPENSSL */
886 #else /* HAVE_CRYPTO */
889 * Cryptography Support Disabled
892 /* Message Digest Structure */
894 crypto_digest_t type;
901 /* Dummy Signature Structure */
905 DIGEST *crypto_digest_new (crypto_digest_t type)
909 digest = (DIGEST *) malloc(sizeof(DIGEST));
913 case CRYPTO_DIGEST_MD5:
914 MD5Init(&digest->md5);
916 case CRYPTO_DIGEST_SHA1:
917 SHA1Init(&digest->sha1);
920 Emsg0(M_ERROR, 0, _("Unsupported digest type specified\n"));
928 int crypto_digest_update (DIGEST *digest, const void *data, size_t length) {
929 switch (digest->type) {
930 case CRYPTO_DIGEST_MD5:
931 /* Doesn't return anything ... */
932 MD5Update(&digest->md5, (unsigned char *) data, length);
934 case CRYPTO_DIGEST_SHA1:
936 if ((ret = SHA1Update(&digest->sha1, (const u_int8_t *) data, length)) == shaSuccess) {
939 Emsg1(M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
948 int crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) {
950 switch (digest->type) {
951 case CRYPTO_DIGEST_MD5:
952 /* Guard against programmer error by either the API client or
953 * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */
954 assert(*length >= CRYPTO_DIGEST_MD5_SIZE);
955 *length = CRYPTO_DIGEST_MD5_SIZE;
956 /* Doesn't return anything ... */
957 MD5Final((unsigned char *) dest, &digest->md5);
959 case CRYPTO_DIGEST_SHA1:
960 /* Guard against programmer error by either the API client or
961 * an out-of-sync CRYPTO_DIGEST_MAX_SIZE */
962 assert(*length >= CRYPTO_DIGEST_SHA1_SIZE);
963 *length = CRYPTO_DIGEST_SHA1_SIZE;
964 if (SHA1Final(&digest->sha1, (u_int8_t *) dest) == shaSuccess) {
977 void crypto_digest_free (DIGEST *digest)
983 int init_crypto (void) { return 0; }
984 int cleanup_crypto (void) { return 0; }
986 SIGNATURE *crypto_sign_new (void) { return NULL; }
988 crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; }
989 crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; }
991 int crypto_sign_add_signer (SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; }
992 int crypto_sign_encode (SIGNATURE *sig, void *dest, size_t *length) { return false; }
994 SIGNATURE *crypto_sign_decode (const void *sigData, size_t length) { return false; }
995 void crypto_sign_free (SIGNATURE *sig) { }
998 X509_KEYPAIR *crypto_keypair_new (void) { return NULL; }
999 int crypto_keypair_load_cert (X509_KEYPAIR *keypair, const char *file) { return false; }
1000 int crypto_keypair_load_key (X509_KEYPAIR *keypair, const char *file, CRYPTO_PEM_PASSWD_CB *pem_callback, const void *pem_userdata) { return false; }
1001 void crypto_keypair_free (X509_KEYPAIR *keypair) { }
1003 #endif /* HAVE_CRYPTO */
1008 * Default PEM encryption passphrase callback.
1009 * Returns an empty password.
1011 int crypto_default_pem_callback(char *buf, int size, const void *userdata)
1013 bstrncpy(buf, "", size);
1014 return (strlen(buf));
1018 * Returns the ASCII name of the digest type.
1019 * Returns: ASCII name of digest type.
1021 const char *crypto_digest_name (DIGEST *digest) {
1022 switch (digest->type) {
1023 case CRYPTO_DIGEST_MD5:
1025 case CRYPTO_DIGEST_SHA1:
1027 case CRYPTO_DIGEST_SHA256:
1029 case CRYPTO_DIGEST_SHA512:
1031 case CRYPTO_DIGEST_NONE:
1034 return "Invalid Digest Type";
1040 * Given a stream type, returns the associated
1041 * crypto_digest_t value.
1043 crypto_digest_t crypto_digest_stream_type (int stream) {
1045 case STREAM_MD5_DIGEST:
1046 return CRYPTO_DIGEST_MD5;
1047 case STREAM_SHA1_DIGEST:
1048 return CRYPTO_DIGEST_SHA1;
1049 case STREAM_SHA256_DIGEST:
1050 return CRYPTO_DIGEST_SHA256;
1051 case STREAM_SHA512_DIGEST:
1052 return CRYPTO_DIGEST_SHA512;
1054 return CRYPTO_DIGEST_NONE;
1059 * * Given a crypto_error_t value, return the associated
1062 const char *crypto_strerror(crypto_error_t error) {
1064 case CRYPTO_ERROR_NONE:
1066 case CRYPTO_ERROR_NOSIGNER:
1067 return "Signer not found";
1068 case CRYPTO_ERROR_INVALID_DIGEST:
1069 return "Unsupported digest algorithm";
1070 case CRYPTO_ERROR_BAD_SIGNATURE:
1071 return "Signature is invalid";
1072 case CRYPTO_ERROR_INTERNAL:
1073 /* This shouldn't happen */
1074 return "Internal error";
1076 return "Unknown error";