X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fcrypto.c;h=af206985dc53493558904b4c873cc89ae105fda8;hb=95c6245affef4000580427d5e0855227dedcd9dc;hp=f1639e71d63ae8c9a05c7937d0c0c418f5fe1cc0;hpb=a0452019ed5636a46042f0fafef7d30fd1f7d785;p=bacula%2Fbacula diff --git a/bacula/src/lib/crypto.c b/bacula/src/lib/crypto.c index f1639e71d6..af206985dc 100644 --- a/bacula/src/lib/crypto.c +++ b/bacula/src/lib/crypto.c @@ -19,7 +19,7 @@ * license please contact Landon Fuller . */ /* - Copyright (C) 2005 Kern Sibbald + Copyright (C) 2005-2006 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -176,6 +176,7 @@ ASN1_SEQUENCE(SignatureData) = { ASN1_SEQUENCE(CryptoData) = { ASN1_SIMPLE(CryptoData, version, ASN1_INTEGER), + ASN1_SIMPLE(CryptoData, contentEncryptionAlgorithm, ASN1_OBJECT), ASN1_SIMPLE(CryptoData, iv, ASN1_OCTET_STRING), ASN1_SET_OF(CryptoData, recipientInfo, RecipientInfo) } ASN1_SEQUENCE_END(CryptoData); @@ -579,7 +580,7 @@ DIGEST *crypto_digest_new (crypto_digest_t type) DIGEST *digest; const EVP_MD *md = NULL; /* Quell invalid uninitialized warnings */ - digest = (DIGEST *) malloc(sizeof(DIGEST)); + digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; /* Initialize the OpenSSL message digest context */ @@ -625,7 +626,8 @@ err: * Returns: true on success * false on failure */ -bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) { +bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) +{ if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) { return true; } else { @@ -640,8 +642,8 @@ bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) { * Returns: true on success * false on failure */ -bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) { - if (!EVP_DigestFinal(&digest->ctx, (unsigned char *) dest, (unsigned int *) length)) { +bool crypto_digest_finalize (DIGEST *digest, uint8_t *dest, uint32_t *length) { + if (!EVP_DigestFinal(&digest->ctx, dest, (unsigned int *)length)) { return false; } else { return true; @@ -873,14 +875,14 @@ err: * Returns: true on success, stores the encoded data in dest, and the size in length. * false on failure. */ -int crypto_sign_encode(SIGNATURE *sig, void *dest, size_t *length) +int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length) { if (*length == 0) { *length = i2d_SignatureData(sig->sigData, NULL); return true; } - *length = i2d_SignatureData(sig->sigData, (unsigned char **) &dest); + *length = i2d_SignatureData(sig->sigData, (unsigned char **)&dest); return true; } @@ -893,16 +895,16 @@ int crypto_sign_encode(SIGNATURE *sig, void *dest, size_t *length) */ -SIGNATURE *crypto_sign_decode(const void *sigData, size_t length) +SIGNATURE *crypto_sign_decode(const uint8_t *sigData, uint32_t length) { SIGNATURE *sig; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) const unsigned char *p = (const unsigned char *) sigData; #else - unsigned char *p = (unsigned char *) sigData; + unsigned char *p = (unsigned char *)sigData; #endif - sig = (SIGNATURE *) malloc(sizeof(SIGNATURE)); + sig = (SIGNATURE *)malloc(sizeof(SIGNATURE)); if (!sig) { return NULL; } @@ -913,6 +915,7 @@ SIGNATURE *crypto_sign_decode(const void *sigData, size_t length) if (!sig->sigData) { /* Allocation / Decoding failed in OpenSSL */ openssl_post_errors(M_ERROR, _("Signature decoding failed")); + free(sig); return NULL; } @@ -1099,14 +1102,14 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) * Returns: true on success, stores the encoded data in dest, and the size in length. * false on failure. */ -bool crypto_session_encode(CRYPTO_SESSION *cs, void *dest, size_t *length) +bool crypto_session_encode(CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { if (*length == 0) { *length = i2d_CryptoData(cs->cryptoData, NULL); return true; } - *length = i2d_CryptoData(cs->cryptoData, (unsigned char **) &dest); + *length = i2d_CryptoData(cs->cryptoData, &dest); return true; } @@ -1119,23 +1122,31 @@ bool crypto_session_encode(CRYPTO_SESSION *cs, void *dest, size_t *length) * Returns: CRYPTO_ERROR_NONE and a pointer to a newly allocated CRYPTO_SESSION structure in *session on success. * A crypto_error_t value on failure. */ -crypto_error_t crypto_session_decode(const void *data, size_t length, alist *keypairs, CRYPTO_SESSION **session) +crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { CRYPTO_SESSION *cs; X509_KEYPAIR *keypair; STACK_OF(RecipientInfo) *recipients; crypto_error_t retval = CRYPTO_ERROR_NONE; #if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) - const unsigned char *p = (const unsigned char *) data; + const unsigned char *p = (const unsigned char *)data; #else - unsigned char *p = (unsigned char *) data; + unsigned char *p = (unsigned char *)data; #endif + /* bacula-fd.conf doesn't contains any key */ + if (!keypairs) { + return CRYPTO_ERROR_NORECIPIENT; + } + cs = (CRYPTO_SESSION *) malloc(sizeof(CRYPTO_SESSION)); if (!cs) { return CRYPTO_ERROR_INTERNAL; } + /* Initialize required fields */ + cs->session_key = NULL; + /* d2i_CryptoData modifies the supplied pointer */ cs->cryptoData = d2i_CryptoData(NULL, &p, length); @@ -1224,7 +1235,7 @@ void crypto_session_free (CRYPTO_SESSION *cs) * Returns: A pointer to a CIPHER_CONTEXT object on success. The cipher block size is returned in blocksize. * NULL on failure. */ -CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, size_t *blocksize) +CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { CIPHER_CONTEXT *cipher_ctx; const EVP_CIPHER *ec; @@ -1239,7 +1250,7 @@ CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, size_t *blo */ if ((ec = EVP_get_cipherbyobj(cs->cryptoData->contentEncryptionAlgorithm)) == NULL) { Emsg1(M_ERROR, 0, _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm)); - crypto_cipher_free(cipher_ctx); + free(cipher_ctx); return NULL; } @@ -1291,8 +1302,9 @@ err: * Returns: true on success, number of bytes output in written * false on failure */ -bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const void *data, size_t length, const void *dest, size_t *written) { - if (!EVP_CipherUpdate(&cipher_ctx->ctx, (unsigned char *) dest, (int *) written, (const unsigned char *) data, length)) { +bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) +{ + if (!EVP_CipherUpdate(&cipher_ctx->ctx, (unsigned char *)dest, (int *)written, (const unsigned char *)data, length)) { /* This really shouldn't fail */ return false; } else { @@ -1308,8 +1320,9 @@ bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const void *data, size_t * Returns: true on success * false on failure */ -bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, void *dest, size_t *written) { - if (!EVP_CipherFinal_ex(&cipher_ctx->ctx, (unsigned char *) dest, (int *) written)) { +bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) +{ + if (!EVP_CipherFinal_ex(&cipher_ctx->ctx, (unsigned char *)dest, (int *) written)) { /* This really shouldn't fail */ return false; } else { @@ -1345,9 +1358,12 @@ int init_crypto (void) /* Load libssl and libcrypto human-readable error strings */ SSL_load_error_strings(); - /* Register OpenSSL ciphers */ + /* Initialize OpenSSL SSL library */ SSL_library_init(); + /* Register OpenSSL ciphers and digests */ + OpenSSL_add_all_algorithms(); + if (!openssl_seed_prng()) { Emsg0(M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n")); } @@ -1383,6 +1399,9 @@ int cleanup_crypto (void) /* Free libssl and libcrypto error strings */ ERR_free_strings(); + /* Free all ciphers and digests */ + EVP_cleanup(); + /* Free memory used by PRNG */ RAND_cleanup(); @@ -1419,7 +1438,7 @@ DIGEST *crypto_digest_new (crypto_digest_t type) { DIGEST *digest; - digest = (DIGEST *) malloc(sizeof(DIGEST)); + digest = (DIGEST *)malloc(sizeof(DIGEST)); digest->type = type; switch (type) { @@ -1438,7 +1457,8 @@ DIGEST *crypto_digest_new (crypto_digest_t type) return (digest); } -bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) { +bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) +{ switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ @@ -1458,8 +1478,8 @@ bool crypto_digest_update (DIGEST *digest, const void *data, size_t length) { } } -bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) { - +bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length) +{ switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Guard against programmer error by either the API client or @@ -1467,7 +1487,7 @@ bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) { assert(*length >= CRYPTO_DIGEST_MD5_SIZE); *length = CRYPTO_DIGEST_MD5_SIZE; /* Doesn't return anything ... */ - MD5Final((unsigned char *) dest, &digest->md5); + MD5Final((unsigned char *)dest, &digest->md5); return true; case CRYPTO_DIGEST_SHA1: /* Guard against programmer error by either the API client or @@ -1487,7 +1507,7 @@ bool crypto_digest_finalize (DIGEST *digest, void *dest, size_t *length) { return false; } -void crypto_digest_free (DIGEST *digest) +void crypto_digest_free(DIGEST *digest) { free (digest); } @@ -1502,9 +1522,9 @@ crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DI 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; } -int crypto_sign_encode (SIGNATURE *sig, void *dest, size_t *length) { return false; } +int crypto_sign_encode (SIGNATURE *sig, uint8_t *dest, uint32_t *length) { return false; } -SIGNATURE *crypto_sign_decode (const void *sigData, size_t length) { return NULL; } +SIGNATURE *crypto_sign_decode (const uint8_t *sigData, uint32_t length) { return NULL; } void crypto_sign_free (SIGNATURE *sig) { } @@ -1517,12 +1537,12 @@ void crypto_keypair_free (X509_KEYPAIR *keypair) { } CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys) { return NULL; } void crypto_session_free (CRYPTO_SESSION *cs) { } -bool crypto_session_encode (CRYPTO_SESSION *cs, void *dest, size_t *length) { return false; } -crypto_error_t crypto_session_decode (const void *data, size_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; } +bool crypto_session_encode (CRYPTO_SESSION *cs, uint8_t *dest, uint32_t *length) { return false; } +crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist *keypairs, CRYPTO_SESSION **session) { return CRYPTO_ERROR_INTERNAL; } -CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, size_t *blocksize) { return NULL; } -bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const void *data, size_t length, const void *dest, size_t *written) { return false; } -bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, void *dest, size_t *written) { return false; } +CIPHER_CONTEXT *crypto_cipher_new (CRYPTO_SESSION *cs, bool encrypt, uint32_t *blocksize) { return NULL; } +bool crypto_cipher_update (CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written) { return false; } +bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written) { return false; } void crypto_cipher_free (CIPHER_CONTEXT *cipher_ctx) { } #endif /* HAVE_CRYPTO */