]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/crypto.c
Tweak version date
[bacula/bacula] / bacula / src / lib / crypto.c
index ce1dd97daf38d11d241264d251879773dcffcd91..7ffa20ecc52227bbea2e33bf75424b996ede3456 100644 (file)
@@ -1,26 +1,26 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2005-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation plus additions
-   that are listed in the file LICENSE.
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
 
    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
@@ -30,8 +30,6 @@
  *
  * Author: Landon Fuller <landonf@opendarwin.org>
  *
- * Version $Id$
- *
  * This file was contributed to the Bacula project by Landon Fuller.
  *
  * Landon Fuller has been granted a perpetual, worldwide, non-exclusive,
 #include "jcr.h"
 #include <assert.h>
 
+/**
+ * For OpenSSL version 1.x, EVP_PKEY_encrypt no longer
+ *  exists.  It was not an official API.
+ */
+#ifdef HAVE_OPENSSLv1
+#define EVP_PKEY_encrypt EVP_PKEY_encrypt_old
+#define EVP_PKEY_decrypt EVP_PKEY_decrypt_old
+#endif
+
 /*
  * Bacula ASN.1 Syntax
  *
@@ -309,7 +316,7 @@ typedef struct PEM_CB_Context {
  */
 static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
    X509_EXTENSION *ext;
-   X509V3_EXT_METHOD *method;
+   const X509V3_EXT_METHOD *method;
    ASN1_OCTET_STRING *keyid;
    int i;
 #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
@@ -451,13 +458,15 @@ int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file)
 
    /* Extract the subjectKeyIdentifier extension field */
    if ((keypair->keyid = openssl_cert_keyid(cert)) == NULL) {
-      Emsg0(M_ERROR, 0, _("Provided certificate does not include the required subjectKeyIdentifier extension."));
+      Jmsg0(NULL, M_ERROR, 0,
+         _("Provided certificate does not include the required subjectKeyIdentifier extension."));
       goto err;
    }
 
    /* Validate the public key type (only RSA is supported) */
    if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) {
-       Emsg1(M_ERROR, 0, _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
+       Jmsg1(NULL, M_ERROR, 0, 
+             _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
        goto err;
    }
 
@@ -595,7 +604,7 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
    digest = (DIGEST *)malloc(sizeof(DIGEST));
    digest->type = type;
    digest->jcr = jcr;
-   Dmsg1(50, "crypto_digest_new jcr=%p\n", jcr);
+   Dmsg1(150, "crypto_digest_new jcr=%p\n", jcr);
 
    /* Initialize the OpenSSL message digest context */
    EVP_MD_CTX_init(&digest->ctx);
@@ -630,7 +639,7 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
 
 err:
    /* This should not happen, but never say never ... */
-   Dmsg0(50, "Digest init failed.\n");
+   Dmsg0(150, "Digest init failed.\n");
    openssl_post_errors(jcr, M_ERROR, _("OpenSSL digest initialization failed"));
    crypto_digest_free(digest);
    return NULL;
@@ -644,7 +653,7 @@ err:
 bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
 {
    if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) {
-      Dmsg0(50, "digest update failed\n");
+      Dmsg0(150, "digest update failed\n");
       openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest update failed"));
       return false;
    } else { 
@@ -662,7 +671,7 @@ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
 bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length)
 {
    if (!EVP_DigestFinal(&digest->ctx, dest, (unsigned int *)length)) {
-      Dmsg0(50, "digest finalize failed\n");
+      Dmsg0(150, "digest finalize failed\n");
       openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest finalize failed"));
       return false;
    } else {
@@ -695,7 +704,7 @@ SIGNATURE *crypto_sign_new(JCR *jcr)
 
    sig->sigData = SignatureData_new();
    sig->jcr = jcr;
-   Dmsg1(50, "crypto_sign_new jcr=%p\n", jcr);
+   Dmsg1(150, "crypto_sign_new jcr=%p\n", jcr);
 
    if (!sig->sigData) {
       /* Allocation failed in OpenSSL */
@@ -711,11 +720,13 @@ SIGNATURE *crypto_sign_new(JCR *jcr)
 
 /*
  * For a given public key, find the associated SignatureInfo record
- * and create a digest context for signature validation
+ *   and create a digest context for signature validation
+ *
  * Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest.
  *          A crypto_error_t value on failure.
  */
-crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest)
+crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, 
+                                      crypto_digest_t &type, DIGEST **digest)
 {
    STACK_OF(SignerInfo) *signers;
    SignerInfo *si;
@@ -727,23 +738,32 @@ crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, DIG
       si = sk_SignerInfo_value(signers, i);
       if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
          /* Get the digest algorithm and allocate a digest context */
-         Dmsg1(50, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
+         Dmsg1(150, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
          switch (OBJ_obj2nid(si->digestAlgorithm)) {
          case NID_md5:
+            Dmsg0(100, "sign digest algorithm is MD5\n");
+            type = CRYPTO_DIGEST_MD5;
             *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_MD5);
             break;
          case NID_sha1:
+            Dmsg0(100, "sign digest algorithm is SHA1\n");
+            type = CRYPTO_DIGEST_SHA1;
             *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA1);
             break;
 #ifdef HAVE_SHA2
          case NID_sha256:
+            Dmsg0(100, "sign digest algorithm is SHA256\n");
+            type = CRYPTO_DIGEST_SHA256;
             *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA256);
             break;
          case NID_sha512:
+            Dmsg0(100, "sign digest algorithm is SHA512\n");
+            type = CRYPTO_DIGEST_SHA512;
             *digest = crypto_digest_new(sig->jcr, CRYPTO_DIGEST_SHA512);
             break;
 #endif
          default:
+            type = CRYPTO_DIGEST_NONE;
             *digest = NULL;
             return CRYPTO_ERROR_INVALID_DIGEST;
          }
@@ -1002,7 +1022,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_128_cbc);
       ec = EVP_aes_128_cbc();
       break;
-#ifdef HAVE_SHA2
+#ifndef HAVE_OPENSSL_EXPORT_LIBRARY
    case CRYPTO_CIPHER_AES_192_CBC:
       /* AES 192 bit CBC */
       cs->cryptoData->contentEncryptionAlgorithm = OBJ_nid2obj(NID_aes_192_cbc);
@@ -1020,7 +1040,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       ec = EVP_bf_cbc();
       break;
    default:
-      Emsg0(M_ERROR, 0, _("Unsupported cipher type specified\n"));
+      Jmsg0(NULL, M_ERROR, 0, _("Unsupported cipher type specified\n"));
       crypto_session_free(cs);
       return NULL;
    }
@@ -1263,7 +1283,8 @@ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *bl
     * Acquire a cipher instance for the given ASN.1 cipher NID
     */
    if ((ec = EVP_get_cipherbyobj(cs->cryptoData->contentEncryptionAlgorithm)) == NULL) {
-      Emsg1(M_ERROR, 0, _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm));
+      Jmsg1(NULL, M_ERROR, 0, 
+         _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm));
       free(cipher_ctx);
       return NULL;
    }
@@ -1366,7 +1387,9 @@ int init_crypto (void)
    int stat;
 
    if ((stat = openssl_init_threads()) != 0) {
-      Emsg1(M_ABORT, 0, _("Unable to init OpenSSL threading: ERR=%s\n"), strerror(stat));
+      berrno be;
+      Jmsg1(NULL, M_ABORT, 0, 
+        _("Unable to init OpenSSL threading: ERR=%s\n"), be.bstrerror(stat));
    }
 
    /* Load libssl and libcrypto human-readable error strings */
@@ -1379,7 +1402,7 @@ int init_crypto (void)
    OpenSSL_add_all_algorithms();
 
    if (!openssl_seed_prng()) {
-      Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
+      Jmsg0(NULL, M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
    }
 
    crypto_initialized = true;
@@ -1405,7 +1428,7 @@ int cleanup_crypto (void)
    }
 
    if (!openssl_save_prng()) {
-      Emsg0(M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
+      Jmsg0(NULL, M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
    }
 
    openssl_cleanup_threads();
@@ -1486,7 +1509,7 @@ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
       if ((ret = SHA1Update(&digest->sha1, (const u_int8_t *) data, length)) == shaSuccess) {
          return true;
       } else {
-         Emsg1(M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
+         Jmsg1(NULL, M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
          return false;
       }
       break;
@@ -1535,7 +1558,10 @@ int cleanup_crypto (void) { return 0; }
 
 SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; }
 
-crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; }
+crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, 
+                                       crypto_digest_t &type, DIGEST **digest) 
+   { return CRYPTO_ERROR_INTERNAL; }
+
 crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; }
 
 int crypto_sign_add_signer (SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; }