mirror of https://github.com/Cisco-Talos/clamav
commit
b842e8bf75
File diff suppressed because it is too large
Load Diff
@ -1,35 +0,0 @@ |
||||
/* Sha256.h -- SHA-256 Hash
|
||||
2010-06-11 : Igor Pavlov : Public domain */ |
||||
|
||||
#ifndef __CRYPTO_SHA256_H |
||||
#define __CRYPTO_SHA256_H |
||||
|
||||
#include "Types.h" |
||||
|
||||
EXTERN_C_BEGIN |
||||
|
||||
#define SHA256_DIGEST_SIZE 32 |
||||
|
||||
#define __USE_CLAM_SHA256_FOR_7Z__ |
||||
|
||||
#ifndef __USE_CLAM_SHA256_FOR_7Z__ |
||||
typedef struct |
||||
{ |
||||
UInt32 state[8]; |
||||
UInt64 count; |
||||
Byte buffer[64]; |
||||
} CSha256; |
||||
|
||||
void Sha256_Init(CSha256 *p); |
||||
void Sha256_Update(CSha256 *p, const Byte *data, size_t size); |
||||
void Sha256_Final(CSha256 *p, Byte *digest); |
||||
#else |
||||
#include "../sha256.h" |
||||
#define CSha256 SHA256_CTX |
||||
#define Sha256_Init sha256_init |
||||
#define Sha256_Update sha256_update |
||||
#define Sha256_Final sha256_final |
||||
#endif |
||||
EXTERN_C_END |
||||
|
||||
#endif |
@ -0,0 +1,189 @@ |
||||
/*
|
||||
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. |
||||
* |
||||
* Author: Shawn Webb |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* 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 |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#if HAVE_CONF_H |
||||
#include "clamav-config.h" |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#ifdef HAVE_UNISTD_H |
||||
#include <unistd.h> |
||||
#endif |
||||
|
||||
#include <math.h> |
||||
|
||||
#include <sys/types.h> |
||||
|
||||
#include <openssl/bio.h> |
||||
#include <openssl/evp.h> |
||||
|
||||
#include "libclamav/conv.h" |
||||
#include "libclamav/crypto.h" |
||||
|
||||
/** Get the expected decoded length of a base64-encoded string
|
||||
* @param[in] data Base64-encoded string |
||||
* @param[in] len length of the string |
||||
* @return The expected decoded length of the base64-encoded string |
||||
*/ |
||||
static size_t base64_len(const char *data, size_t len) |
||||
{ |
||||
int padding=0; |
||||
size_t i; |
||||
|
||||
if (!len) |
||||
return 0; |
||||
|
||||
for (i=len-1; i > 0 && data[i] == '='; i--) |
||||
padding++; |
||||
|
||||
return (size_t)((3*len)/4 - padding); |
||||
} |
||||
|
||||
/** Decode a base64-encoded string
|
||||
* @param[in] data The base64-encoded string |
||||
* @param[in] len Length of the base64-encoded string |
||||
* @param[out] obuf If obuf is not set to NULL, store the decoded data in obuf. Otherwise, the decoded data is stored in a dynamically-allocated buffer. |
||||
* @param[out] olen The length of the decoded data |
||||
* @return The base64-decoded data |
||||
*/ |
||||
void *cl_base64_decode(char *data, size_t len, void *obuf, size_t *olen) |
||||
{ |
||||
BIO *bio, *b64; |
||||
void *buf, *ret; |
||||
|
||||
buf = (obuf) ? obuf : malloc(base64_len(data, len)+1); |
||||
if (!(buf)) |
||||
return NULL; |
||||
|
||||
b64 = BIO_new(BIO_f_base64()); |
||||
if (!(b64)) { |
||||
if (!(obuf)) |
||||
free(buf); |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
bio = BIO_new_mem_buf(data, len); |
||||
if (!(bio)) { |
||||
BIO_free(b64); |
||||
if (!(obuf)) |
||||
free(buf); |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
bio = BIO_push(b64, bio); |
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); |
||||
|
||||
*olen = BIO_read(bio, buf, base64_len(data, len)); |
||||
|
||||
BIO_free_all(bio); |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
/** Base64-encode data
|
||||
* @param[in] data The data to be encoded |
||||
* @param[in] len The length of the data |
||||
* @return A pointer to the base64-encoded data. The data is stored in a dynamically-allocated buffer. |
||||
*/ |
||||
char *cl_base64_encode(void *data, size_t len) |
||||
{ |
||||
BIO *bio, *b64; |
||||
char *buf, *p; |
||||
size_t elen; |
||||
|
||||
b64 = BIO_new(BIO_f_base64()); |
||||
bio = BIO_new(BIO_s_mem()); |
||||
|
||||
bio = BIO_push(b64, bio); |
||||
BIO_write(bio, data, len); |
||||
|
||||
BIO_flush(bio); |
||||
elen = (size_t)BIO_get_mem_data(bio, &buf); |
||||
|
||||
/* Ensure we're dealing with a NULL-terminated string */ |
||||
p = (char *)malloc(elen+1); |
||||
memcpy((void *)p, (void *)buf, elen); |
||||
p[elen] = 0x00; |
||||
buf = p; |
||||
|
||||
BIO_free_all(bio); |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
#if defined(CONV_SELF_TEST) |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
char *plaintext, *encoded, *decoded; |
||||
unsigned char *sha_plaintext, *sha_decoded; |
||||
size_t len; |
||||
int ret=0; |
||||
unsigned int shalen; |
||||
|
||||
initialize_crypto(); |
||||
|
||||
plaintext = (argv[1]) ? argv[1] : "Hello. This is dog"; |
||||
sha_plaintext = sha256(plaintext, strlen(plaintext), NULL, NULL); |
||||
if (!(sha_plaintext)) { |
||||
fprintf(stderr, "Could not generate sha256 of plaintext\n"); |
||||
return 1; |
||||
} |
||||
|
||||
encoded = base64_encode(plaintext, strlen(plaintext)); |
||||
if (!(encoded)) { |
||||
fprintf(stderr, "Could not base64 encode plaintest\n"); |
||||
return 1; |
||||
} |
||||
fprintf(stderr, "Base64 encoded: %s\n", encoded); |
||||
|
||||
decoded = base64_decode(encoded, strlen(encoded), NULL, &len); |
||||
if (!(decoded)) { |
||||
fprintf(stderr, "Could not base64 decoded string\n"); |
||||
return 1; |
||||
} |
||||
|
||||
sha_decoded = sha256(decoded, len, NULL, &shalen); |
||||
if (!(sha_decoded)) { |
||||
fprintf(stderr, "Could not generate sha256 of decoded data\n"); |
||||
return 1; |
||||
} |
||||
|
||||
if (memcmp(sha_plaintext, sha_decoded, shalen)) { |
||||
fprintf(stderr, "Decoded does not match plaintext: %s\n", decoded); |
||||
ret = 1; |
||||
} |
||||
|
||||
free(sha_decoded); |
||||
free(sha_plaintext); |
||||
free(encoded); |
||||
free(decoded); |
||||
|
||||
cleanup_crypto(); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,27 @@ |
||||
/*
|
||||
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. |
||||
* |
||||
* Author: Shawn Webb |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* 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 |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#if !defined(_CLAMAV_CONV_H) |
||||
#define _CLAMAV_CONV_H |
||||
|
||||
void *cl_base64_decode(char *, size_t, void *, size_t *); |
||||
char *cl_base64_encode(void *, size_t); |
||||
|
||||
#endif |
@ -0,0 +1,958 @@ |
||||
/*
|
||||
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. |
||||
* |
||||
* Author: Shawn Webb |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* 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 |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#if HAVE_CONFIG_H |
||||
#include "clamav-config.h" |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include <time.h> |
||||
|
||||
#ifdef _WIN32 |
||||
#include <io.h> |
||||
#endif |
||||
|
||||
#include <sys/types.h> |
||||
#include <dirent.h> |
||||
#include <sys/stat.h> |
||||
#include <fcntl.h> |
||||
|
||||
#if !defined(_WIN32) |
||||
#include <unistd.h> |
||||
#endif |
||||
|
||||
#include <openssl/ssl.h> |
||||
#include <openssl/err.h> |
||||
#include "libclamav/crypto.h" |
||||
|
||||
#include "clamav.h" |
||||
#include "default.h" |
||||
#include "others.h" |
||||
#include "libclamav/conv.h" |
||||
#include "libclamav/str.h" |
||||
|
||||
#if defined(_WIN32) |
||||
char * strptime(const char *buf, const char *fmt, struct tm *tm); |
||||
#endif |
||||
|
||||
#if !defined(MIN) |
||||
#define MIN(x,y) ((x)<(y)?(x):(y)) |
||||
#endif |
||||
|
||||
int cl_initialize_crypto(void) |
||||
{ |
||||
SSL_load_error_strings(); |
||||
SSL_library_init(); |
||||
OpenSSL_add_all_digests(); |
||||
OpenSSL_add_all_algorithms(); |
||||
OpenSSL_add_all_ciphers(); |
||||
ERR_load_crypto_strings(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void cl_cleanup_crypto(void) |
||||
{ |
||||
EVP_cleanup(); |
||||
} |
||||
|
||||
unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned char *obuf, unsigned int *olen) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
unsigned char *ret; |
||||
size_t mdsz; |
||||
const EVP_MD *md; |
||||
unsigned int i; |
||||
size_t cur; |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) |
||||
return NULL; |
||||
|
||||
mdsz = EVP_MD_size(md); |
||||
|
||||
ret = (obuf != NULL) ? obuf : (unsigned char *)malloc(mdsz); |
||||
if (!(ret)) |
||||
return NULL; |
||||
|
||||
if (!EVP_DigestInit(&ctx, md)) { |
||||
if (!(obuf)) |
||||
free(ret); |
||||
|
||||
if ((olen)) |
||||
*olen = 0; |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
cur=0; |
||||
while (cur < len) { |
||||
size_t todo = MIN(EVP_MD_block_size(md), len-cur); |
||||
if (!EVP_DigestUpdate(&ctx, (void *)(((unsigned char *)buf)+cur), todo)) { |
||||
if (!(obuf)) |
||||
free(ret); |
||||
|
||||
if ((olen)) |
||||
*olen = 0; |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
cur += todo; |
||||
} |
||||
|
||||
if (!EVP_DigestFinal(&ctx, ret, &i)) { |
||||
if (!(obuf)) |
||||
free(ret); |
||||
|
||||
if ((olen)) |
||||
*olen = 0; |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
EVP_MD_CTX_cleanup(&ctx); |
||||
|
||||
if ((olen)) |
||||
*olen = i; |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
unsigned char *cl_hash_file_fd(int fd, char *alg, unsigned int *olen) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
const EVP_MD *md; |
||||
unsigned char *res; |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) |
||||
return NULL; |
||||
|
||||
if (!EVP_DigestInit(&ctx, md)) { |
||||
return NULL; |
||||
} |
||||
|
||||
res = cl_hash_file_fd_ctx(&ctx, fd, olen); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen) |
||||
{ |
||||
unsigned char *buf; |
||||
unsigned char *hash; |
||||
int mdsz; |
||||
unsigned int hashlen; |
||||
struct stat sb; |
||||
|
||||
unsigned int blocksize; |
||||
|
||||
#ifdef _WIN32 |
||||
int nread; |
||||
#else |
||||
ssize_t nread; |
||||
#endif |
||||
|
||||
mdsz = EVP_MD_CTX_size(ctx); |
||||
|
||||
if (fstat(fd, &sb) < 0) { |
||||
return NULL; |
||||
} |
||||
|
||||
#ifdef _WIN32 |
||||
blocksize = 8192; |
||||
#else |
||||
blocksize = sb.st_blksize; |
||||
#endif |
||||
|
||||
buf = (unsigned char *)malloc(blocksize); |
||||
if (!(buf)) { |
||||
return NULL; |
||||
} |
||||
|
||||
hash = (unsigned char *)malloc(mdsz); |
||||
if (!(hash)) { |
||||
free(buf); |
||||
return NULL; |
||||
} |
||||
|
||||
#ifdef _WIN32 |
||||
while ((nread = _read(fd, buf, blocksize)) > 0) { |
||||
#else |
||||
while ((nread = read(fd, buf, blocksize)) > 0) { |
||||
#endif |
||||
if (!EVP_DigestUpdate(ctx, buf, nread)) { |
||||
free(buf); |
||||
free(hash); |
||||
|
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
if (!EVP_DigestFinal(ctx, hash, &hashlen)) { |
||||
free(hash); |
||||
free(buf); |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
EVP_MD_CTX_cleanup(&ctx); |
||||
|
||||
if ((olen)) |
||||
*olen = hashlen; |
||||
|
||||
free(buf); |
||||
|
||||
return hash; |
||||
} |
||||
|
||||
unsigned char *cl_hash_file_fp(FILE *fp, char *alg, unsigned int *olen) |
||||
{ |
||||
return cl_hash_file_fd(fileno(fp), alg, olen); |
||||
} |
||||
|
||||
unsigned char *cl_sha256(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen) |
||||
{ |
||||
return cl_hash_data("sha256", buf, len, obuf, olen); |
||||
} |
||||
|
||||
unsigned char *cl_sha1(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen) |
||||
{ |
||||
return cl_hash_data("sha1", buf, len, obuf, olen); |
||||
} |
||||
|
||||
int cl_verify_signature_hash(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
const EVP_MD *md; |
||||
size_t mdsz; |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) |
||||
return -1; |
||||
|
||||
mdsz = EVP_MD_size(md); |
||||
|
||||
if (!EVP_VerifyInit(&ctx, md)) { |
||||
return -1; |
||||
} |
||||
|
||||
if (!EVP_VerifyUpdate(&ctx, digest, mdsz)) { |
||||
return -1; |
||||
} |
||||
|
||||
if (EVP_VerifyFinal(&ctx, sig, siglen, pkey) != 0) { |
||||
return -1; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int cl_verify_signature_fd(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, int fd) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
const EVP_MD *md; |
||||
size_t mdsz; |
||||
unsigned char *digest; |
||||
|
||||
digest = cl_hash_file_fd(fd, alg, NULL); |
||||
if (!(digest)) |
||||
return -1; |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) |
||||
return -1; |
||||
|
||||
mdsz = EVP_MD_size(md); |
||||
|
||||
if (!EVP_VerifyInit(&ctx, md)) { |
||||
free(digest); |
||||
return -1; |
||||
} |
||||
|
||||
if (!EVP_VerifyUpdate(&ctx, digest, mdsz)) { |
||||
free(digest); |
||||
return -1; |
||||
} |
||||
|
||||
if (EVP_VerifyFinal(&ctx, sig, siglen, pkey) != 0) { |
||||
free(digest); |
||||
return -1; |
||||
} |
||||
|
||||
free(digest); |
||||
return 0; |
||||
} |
||||
|
||||
int cl_verify_signature(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
const EVP_MD *md; |
||||
size_t mdsz; |
||||
unsigned char *digest; |
||||
|
||||
if (decode) { |
||||
unsigned char *newsig; |
||||
size_t newsiglen; |
||||
|
||||
newsig = (unsigned char *)cl_base64_decode((char *)sig, siglen, NULL, &newsiglen); |
||||
if (!(newsig)) |
||||
return -1; |
||||
|
||||
sig = newsig; |
||||
siglen = newsiglen; |
||||
} |
||||
|
||||
digest = cl_hash_data(alg, data, datalen, NULL, NULL); |
||||
if (!(digest)) { |
||||
if (decode) |
||||
free(sig); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) { |
||||
free(digest); |
||||
if (decode) |
||||
free(sig); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
mdsz = EVP_MD_size(md); |
||||
|
||||
if (!EVP_VerifyInit(&ctx, md)) { |
||||
free(digest); |
||||
if (decode) |
||||
free(sig); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
if (!EVP_VerifyUpdate(&ctx, digest, mdsz)) { |
||||
free(digest); |
||||
if (decode) |
||||
free(sig); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
if (EVP_VerifyFinal(&ctx, sig, siglen, pkey) != 0) { |
||||
free(digest); |
||||
if (decode) |
||||
free(sig); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
if (decode) |
||||
free(sig); |
||||
|
||||
free(digest); |
||||
return 0; |
||||
} |
||||
|
||||
int cl_verify_signature_hash_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest) |
||||
{ |
||||
X509 *x509; |
||||
FILE *fp; |
||||
int res; |
||||
|
||||
fp = fopen(x509path, "r"); |
||||
if (!(fp)) { |
||||
return -1; |
||||
} |
||||
|
||||
x509 = PEM_read_X509(fp, NULL, NULL, NULL); |
||||
if (!(x509)) { |
||||
fclose(fp); |
||||
return -1; |
||||
} |
||||
|
||||
fclose(fp); |
||||
|
||||
res = cl_verify_signature_hash_x509(x509, alg, sig, siglen, digest); |
||||
|
||||
X509_free(x509); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_verify_signature_fd_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, int fd) |
||||
{ |
||||
X509 *x509; |
||||
FILE *fp; |
||||
int res; |
||||
|
||||
fp = fopen(x509path, "r"); |
||||
if (!(fp)) { |
||||
return -1; |
||||
} |
||||
|
||||
x509 = PEM_read_X509(fp, NULL, NULL, NULL); |
||||
if (!(x509)) { |
||||
fclose(fp); |
||||
return -1; |
||||
} |
||||
|
||||
fclose(fp); |
||||
|
||||
res = cl_verify_signature_fd_x509(x509, alg, sig, siglen, fd); |
||||
|
||||
X509_free(x509); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_verify_signature_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode) |
||||
{ |
||||
X509 *x509; |
||||
FILE *fp; |
||||
int res; |
||||
|
||||
fp = fopen(x509path, "r"); |
||||
if (!(fp)) { |
||||
return -1; |
||||
} |
||||
|
||||
x509 = PEM_read_X509(fp, NULL, NULL, NULL); |
||||
if (!(x509)) { |
||||
fclose(fp); |
||||
return -1; |
||||
} |
||||
|
||||
fclose(fp); |
||||
|
||||
res = cl_verify_signature_x509(x509, alg, sig, siglen, data, datalen, decode); |
||||
|
||||
X509_free(x509); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_verify_signature_hash_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest) |
||||
{ |
||||
EVP_PKEY *pkey; |
||||
int res; |
||||
|
||||
pkey = X509_get_pubkey(x509); |
||||
if (!(pkey)) |
||||
return -1; |
||||
|
||||
res = cl_verify_signature_hash(pkey, alg, sig, siglen, digest); |
||||
|
||||
EVP_PKEY_free(pkey); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_verify_signature_fd_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, int fd) |
||||
{ |
||||
EVP_PKEY *pkey; |
||||
int res; |
||||
|
||||
pkey = X509_get_pubkey(x509); |
||||
if (!(pkey)) |
||||
return -1; |
||||
|
||||
res = cl_verify_signature_fd(pkey, alg, sig, siglen, fd); |
||||
|
||||
EVP_PKEY_free(pkey); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_verify_signature_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode) |
||||
{ |
||||
EVP_PKEY *pkey; |
||||
int res; |
||||
|
||||
pkey = X509_get_pubkey(x509); |
||||
if (!(pkey)) |
||||
return -1; |
||||
|
||||
res = cl_verify_signature(pkey, alg, sig, siglen, data, datalen, decode); |
||||
|
||||
EVP_PKEY_free(pkey); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
unsigned char *cl_sign_data_keyfile(char *keypath, char *alg, unsigned char *hash, unsigned int *olen, int encode) |
||||
{ |
||||
FILE *fp; |
||||
EVP_PKEY *pkey; |
||||
unsigned char *res; |
||||
|
||||
fp = fopen(keypath, "r"); |
||||
if (!(fp)) { |
||||
return NULL; |
||||
} |
||||
|
||||
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); |
||||
if (!(pkey)) { |
||||
fclose(fp); |
||||
return NULL; |
||||
} |
||||
|
||||
fclose(fp); |
||||
|
||||
res = cl_sign_data(pkey, alg, hash, olen, encode); |
||||
|
||||
EVP_PKEY_free(pkey); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
unsigned char *cl_sign_data(EVP_PKEY *pkey, char *alg, unsigned char *hash, unsigned int *olen, int encode) |
||||
{ |
||||
EVP_MD_CTX ctx; |
||||
const EVP_MD *md; |
||||
unsigned int siglen; |
||||
unsigned char *sig; |
||||
|
||||
md = EVP_get_digestbyname(alg); |
||||
if (!(md)) |
||||
return NULL; |
||||
|
||||
sig = (unsigned char *)calloc(1, EVP_PKEY_size(pkey)); |
||||
if (!(sig)) { |
||||
free(hash); |
||||
return NULL; |
||||
} |
||||
|
||||
if (!EVP_SignInit(&ctx, md)) { |
||||
free(sig); |
||||
free(hash); |
||||
return NULL; |
||||
} |
||||
|
||||
if (!EVP_SignUpdate(&ctx, hash, EVP_MD_size(md))) { |
||||
free(sig); |
||||
free(hash); |
||||
return NULL; |
||||
} |
||||
|
||||
if (!EVP_SignFinal(&ctx, sig, &siglen, pkey)) { |
||||
free(sig); |
||||
free(hash); |
||||
return NULL; |
||||
} |
||||
|
||||
if (encode) { |
||||
unsigned char *newsig = (unsigned char *)cl_base64_encode(sig, siglen); |
||||
if (!(newsig)) { |
||||
free(sig); |
||||
free(hash); |
||||
return NULL; |
||||
} |
||||
|
||||
free(sig); |
||||
sig = newsig; |
||||
siglen = (unsigned int)strlen((const char *)newsig); |
||||
} |
||||
|
||||
free(hash); |
||||
|
||||
*olen = siglen; |
||||
return sig; |
||||
} |
||||
|
||||
unsigned char *cl_sign_file_fd(int fd, EVP_PKEY *pkey, char *alg, unsigned int *olen, int encode) |
||||
{ |
||||
unsigned char *hash, *res; |
||||
unsigned int hashlen; |
||||
|
||||
hash = cl_hash_file_fd(fd, alg, &hashlen); |
||||
if (!(hash)) { |
||||
return NULL; |
||||
} |
||||
|
||||
res = cl_sign_data(pkey, alg, hash, olen, encode); |
||||
|
||||
free(hash); |
||||
return res; |
||||
} |
||||
|
||||
unsigned char *cl_sign_file_fp(FILE *fp, EVP_PKEY *pkey, char *alg, unsigned int *olen, int encode) |
||||
{ |
||||
return cl_sign_file_fd(fileno(fp), pkey, alg, olen, encode); |
||||
} |
||||
|
||||
EVP_PKEY *cl_get_pkey_file(char *keypath) |
||||
{ |
||||
EVP_PKEY *pkey; |
||||
FILE *fp; |
||||
|
||||
fp = fopen(keypath, "r"); |
||||
if (!(fp)) |
||||
return NULL; |
||||
|
||||
if (!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))) { |
||||
fclose(fp); |
||||
return NULL; |
||||
} |
||||
|
||||
fclose(fp); |
||||
|
||||
return pkey; |
||||
} |
||||
|
||||
X509 *cl_get_x509_from_mem(void *data, unsigned int len) |
||||
{ |
||||
X509 *cert; |
||||
BIO *cbio; |
||||
|
||||
cbio = BIO_new_mem_buf(data, len); |
||||
if (!(cbio)) |
||||
return NULL; |
||||
|
||||
cert = PEM_read_bio_X509(cbio, NULL, 0, NULL); |
||||
BIO_free(cbio); |
||||
|
||||
return cert; |
||||
} |
||||
|
||||
int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath) |
||||
{ |
||||
char **authorities=NULL, **t, *fullpath; |
||||
size_t nauths = 0; |
||||
int res; |
||||
DIR *dp; |
||||
struct dirent *dirent; |
||||
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2) |
||||
union { |
||||
struct dirent d; |
||||
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1]; |
||||
} result; |
||||
#endif |
||||
|
||||
dp = opendir(tsdir); |
||||
if (!(dp)) |
||||
return CL_EOPEN; |
||||
|
||||
#if defined(HAVE_READDIR_R_3) |
||||
while (!readdir_r(dp, &result.d, &dirent) && dirent) { |
||||
#elif defined(HAVE_READDIR_R_2) |
||||
while ((dirent = (struct dirent *)readdir_r(dp, &result.d))) { |
||||
#else |
||||
while ((dirent = readdir(dp))) { |
||||
#endif |
||||
if (dirent->d_name[0] == '.') |
||||
continue; |
||||
|
||||
if (!cli_strbcasestr(dirent->d_name, ".crt")) |
||||
continue; |
||||
|
||||
t = (char **)realloc(authorities, sizeof(char **) * (nauths + 1)); |
||||
if (!(t)) { |
||||
if (nauths) { |
||||
while (nauths > 0) |
||||
free(authorities[--nauths]); |
||||
free(authorities); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
authorities = t; |
||||
authorities[nauths] = (char *)malloc(strlen(tsdir) + strlen(dirent->d_name) + 2); |
||||
if (!authorities[nauths]) { |
||||
if (nauths) { |
||||
while (nauths > 0) |
||||
free(authorities[nauths--]); |
||||
free(authorities[0]); |
||||
free(authorities); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
sprintf(authorities[nauths], "%s"PATHSEP"%s", tsdir, dirent->d_name); |
||||
nauths++; |
||||
} |
||||
|
||||
t = (char **)realloc(authorities, sizeof(char **) * (nauths + 1)); |
||||
if (!(t)) { |
||||
if (nauths) { |
||||
while (nauths > 0) |
||||
free(authorities[--nauths]); |
||||
free(authorities); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
authorities = t; |
||||
authorities[nauths] = NULL; |
||||
|
||||
closedir(dp); |
||||
|
||||
res = cl_validate_certificate_chain(authorities, NULL, certpath); |
||||
|
||||
while (nauths > 0) |
||||
free(authorities[--nauths]); |
||||
|
||||
free(authorities); |
||||
|
||||
return res; |
||||
} |
||||
|
||||
int cl_validate_certificate_chain(char **authorities, char *crlpath, char *certpath) |
||||
{ |
||||
X509_STORE *store=NULL; |
||||
X509_STORE_CTX *store_ctx; |
||||
X509_LOOKUP *lookup=NULL; |
||||
X509_CRL *crl=NULL; |
||||
X509_VERIFY_PARAM *param=NULL; |
||||
X509 *cert; |
||||
unsigned long i; |
||||
int res; |
||||
|
||||
store = X509_STORE_new(); |
||||
if (!(store)) { |
||||
return -1; |
||||
} |
||||
X509_STORE_set_flags(store, 0); |
||||
|
||||
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); |
||||
if (!(lookup)) { |
||||
X509_STORE_free(store); |
||||
return -1; |
||||
} |
||||
|
||||
if ((crlpath)) { |
||||
|
||||
crl = cl_load_crl(crlpath); |
||||
if (!(crl)) { |
||||
X509_STORE_free(store); |
||||
return -1; |
||||
} |
||||
|
||||
X509_STORE_add_crl(store, crl); |
||||
param = X509_VERIFY_PARAM_new(); |
||||
if ((param)) { |
||||
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); |
||||
X509_STORE_set1_param(store, param); |
||||
} else { |
||||
X509_STORE_free(store); |
||||
X509_CRL_free(crl); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
/* Support multi-tiered setups */ |
||||
for (i=0; authorities[i]; i++) { |
||||
if (!X509_LOOKUP_load_file(lookup, authorities[i], X509_FILETYPE_PEM)) { |
||||
X509_STORE_free(store); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); |
||||
if (!(lookup)) { |
||||
X509_STORE_free(store); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
return -1; |
||||
} |
||||
|
||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); |
||||
|
||||
store_ctx = X509_STORE_CTX_new(); |
||||
if (!(store_ctx)) { |
||||
X509_STORE_free(store); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
return -1; |
||||
} |
||||
|
||||
cert = cl_load_cert(certpath); |
||||
if (!(cert)) { |
||||
X509_STORE_CTX_free(store_ctx); |
||||
X509_STORE_free(store); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { |
||||
X509_STORE_CTX_free(store_ctx); |
||||
X509_STORE_free(store); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
|
||||
X509_free(cert); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
res = X509_verify_cert(store_ctx); |
||||
|
||||
X509_STORE_CTX_free(store_ctx); |
||||
if ((crl)) |
||||
X509_CRL_free(crl); |
||||
|
||||
if ((param)) |
||||
X509_VERIFY_PARAM_free(param); |
||||
|
||||
X509_STORE_free(store); |
||||
|
||||
X509_free(cert); |
||||
|
||||
return (res > 0); |
||||
} |
||||
|
||||
X509 *cl_load_cert(const char *certpath) |
||||
{ |
||||
X509 *cert; |
||||
BIO *bio; |
||||
|
||||
bio = BIO_new(BIO_s_file()); |
||||
if (!(bio)) |
||||
return NULL; |
||||
|
||||
if (BIO_read_filename(bio, certpath) != 1) { |
||||
BIO_free(bio); |
||||
return NULL; |
||||
} |
||||
|
||||
cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL); |
||||
|
||||
BIO_free(bio); |
||||
|
||||
return cert; |
||||
} |
||||
|
||||
struct tm *cl_ASN1_GetTimeT(ASN1_TIME *timeobj) |
||||
{ |
||||
struct tm *t; |
||||
char* str; |
||||
size_t i = 0; |
||||
const char *fmt; |
||||
time_t localt; |
||||
#ifdef _WIN32 |
||||
struct tm localtm, *ltm; |
||||
#else |
||||
struct tm localtm; |
||||
#endif |
||||
|
||||
if (!(timeobj) || !(timeobj->data)) |
||||
return NULL; |
||||
|
||||
str = (char *)(timeobj->data); |
||||
if (strlen(str) < 12) |
||||
return NULL; |
||||
|
||||
t = (struct tm *)calloc(1, sizeof(struct tm)); |
||||
if (!(t)) |
||||
return NULL; |
||||
|
||||
if (timeobj->type == V_ASN1_UTCTIME) { |
||||
/* two digit year */ |
||||
fmt = "%y%m%d%H%M%S"; |
||||
if (str[3] == '0') { |
||||
str[2] = '0'; |
||||
str[3] = '9'; |
||||
} else { |
||||
str[3]--; |
||||
} |
||||
} |
||||
else if (timeobj->type == V_ASN1_GENERALIZEDTIME) { |
||||
/* four digit year */ |
||||
fmt = "%Y%m%d%H%M%S"; |
||||
if (str[5] == '0') { |
||||
str[4] = '0'; |
||||
str[5] = '9'; |
||||
} else { |
||||
str[5]--; |
||||
} |
||||
} |
||||
|
||||
if (!strptime(str, fmt, t)) { |
||||
free(t); |
||||
return NULL; |
||||
} |
||||
|
||||
/* Convert to local time */ |
||||
localt = time(NULL); |
||||
#ifdef _WIN32 |
||||
ltm = localtime(&localt); |
||||
memcpy((void *)(&localtm), (void *)ltm, sizeof(struct tm)); |
||||
#else |
||||
localtime_r(&localt, &localtm); |
||||
#endif |
||||
t->tm_isdst = localtm.tm_isdst; |
||||
return t; |
||||
} |
||||
|
||||
X509_CRL *cl_load_crl(const char *file) |
||||
{ |
||||
X509_CRL *x=NULL; |
||||
FILE *fp; |
||||
struct tm *tm; |
||||
time_t crltime; |
||||
|
||||
if (!(file)) |
||||
return NULL; |
||||
|
||||
fp = fopen(file, "r"); |
||||
if (!(fp)) |
||||
return NULL; |
||||
|
||||
x = PEM_read_X509_CRL(fp, NULL, NULL, NULL); |
||||
|
||||
fclose(fp); |
||||
|
||||
if ((x)) { |
||||
tm = cl_ASN1_GetTimeT(x->crl->nextUpdate); |
||||
if (!(tm)) { |
||||
X509_CRL_free(x); |
||||
return NULL; |
||||
} |
||||
|
||||
#if !defined(_WIN32) |
||||
if (timegm(tm) < time(NULL)) { |
||||
X509_CRL_free(x); |
||||
free(tm); |
||||
return NULL; |
||||
} |
||||
#endif |
||||
|
||||
free(tm); |
||||
} |
||||
|
||||
return x; |
||||
} |
@ -0,0 +1,277 @@ |
||||
/*
|
||||
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved. |
||||
* |
||||
* Author: Shawn Webb |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* 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 |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#if !defined(_CLAMAV_CRYPTO_H) |
||||
#define _CLAMAV_CRYPTO_H |
||||
|
||||
/**
|
||||
* \defgroup CryptoAPI ClamAV Crypto API |
||||
* @{ |
||||
*/ |
||||
|
||||
#define SHA1_HASH_SIZE 20 |
||||
#define SHA256_HASH_SIZE 32 |
||||
|
||||
/**
|
||||
* Initialize the crypto system. |
||||
* @return Always returns 0 |
||||
*/ |
||||
int cl_initialize_crypto(void); |
||||
|
||||
/** Clean up the crypto system prior to program exit.
|
||||
*/ |
||||
void cl_cleanup_crypto(void); |
||||
|
||||
/** Generate a hash of data.
|
||||
@param[in] alg The hashing algorithm to use |
||||
@param[in] buf The data to be hashed |
||||
@param[in] len The length of the to-be-hashed data |
||||
@param[out] obuf An optional buffer to store the generated hash. Use NULL to dynamically allocate buffer. |
||||
@param[out] olen An optional pointer that stores how long the generated hash is. |
||||
@return A pointer to the generated hash or obuf if obuf is not NULL. |
||||
*/ |
||||
unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned char *obuf, unsigned int *olen); |
||||
|
||||
/** Generate a hash of a file.
|
||||
@param[in] ctx A pointer to the OpenSSL EVP_MD_CTX object |
||||
@param[in] fd The file descriptor |
||||
@param[out] olen An optional pointer that stores how long the generated hash is |
||||
@return A pointer to a dynamically-created buffer that holds the generated hash |
||||
*/ |
||||
unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen); |
||||
|
||||
/** Generate a hash of a file.
|
||||
@param[in] fd The file descriptor |
||||
@param[in] alg The hashing algorithm to use |
||||
@param[out] olen An optional pointer that stores how long the generated hash is |
||||
@return A pointer to a dynamically-created buffer that holds the generated hash |
||||
*/ |
||||
unsigned char *cl_hash_file_fd(int fd, char *alg, unsigned int *olen); |
||||
|
||||
/** Generate a hash of a file.
|
||||
@param[in] fp A pointer to a FILE object |
||||
@param[in] alg The hashing algorithm to use |
||||
@param[out] olen An optional pointer that stores how long the generated hash is |
||||
@return A pointer to a dynamically-created buffer that holds the generated hash |
||||
*/ |
||||
unsigned char *cl_hash_file_fp(FILE *fp, char *alg, unsigned int *olen); |
||||
|
||||
/** Generate a sha256 hash of data
|
||||
@param[in] buf The data to hash |
||||
@param[in] len The length of the to-be-hashed data |
||||
@param[out] obuf An optional pointer to store the generated hash. Use NULL to dynamically allocate buffer. |
||||
@param[out] olen An optional pointer that stores how long the generated hash is. |
||||
@return A pointer to the buffer that holds the generated hash |
||||
*/ |
||||
unsigned char *cl_sha256(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen); |
||||
|
||||
/** Generate a sha1 hash of data
|
||||
@param[in] buf The data to hash |
||||
@param[in] len The length of the to-be-hashed data |
||||
@param[out] obuf An optional pointer to store the generated hash. Use NULL to dynamically allocate buffer. |
||||
@param[out] olen An optional pointer that stores how long the generated hash is. |
||||
@return A pointer to the buffer that holds the generated hash or obuf if obuf is not NULL |
||||
*/ |
||||
unsigned char *cl_sha1(const void *buf, size_t len, unsigned char *obuf, unsigned int *olen); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] pkey The public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] data The data that was signed |
||||
@param[in] datalen The length of the data |
||||
@param[in] decode Whether or not to base64-decode the signature prior to verification. 1 for yes, 0 for no. |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] pkey The public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] digest The hash of the signed data |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_hash(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] pkey The public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] fd The file descriptor |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_fd(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned int siglen, int fd); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509path The path to the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] digest The hash of the signed data |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_hash_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509path The path to the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] fd The file descriptor |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_fd_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, int fd); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509path The path to the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] data The data that was signed |
||||
@param[in] datalen The length of the data |
||||
@param[in] decode Whether or not to base64-decode the signature prior to verification. 1 for yes, 0 for no. |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_x509_keyfile(char *x509path, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509 The X509 object of the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] digest The hash of the signed data |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_hash_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *digest); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509 The X509 object of the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] fd The file descriptor |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_fd_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, int fd); |
||||
|
||||
/** Verify validity of signed data
|
||||
@param[in] x509 The X509 object of the public key of the keypair that signed the data |
||||
@param[in] alg The algorithm used to hash the data |
||||
@param[in] sig The signature block |
||||
@param[in] siglen The length of the signature |
||||
@param[in] data The data that was signed |
||||
@param[in] datalen The length of the data |
||||
@param[in] decode Whether or not to base64-decode the signature prior to verification. 1 for yes, 0 for no. |
||||
@return 0 for success, -1 for error or invalid signature |
||||
*/ |
||||
int cl_verify_signature_x509(X509 *x509, char *alg, unsigned char *sig, unsigned int siglen, unsigned char *data, size_t datalen, int decode); |
||||
|
||||
/** Get an X509 object from memory
|
||||
* @param[in] data A pointer to a spot in memory that contains the PEM X509 cert |
||||
* @param[in] len The length of the data |
||||
* @return a pointer to the X509 object on success, NULL on error |
||||
*/ |
||||
X509 *cl_get_x509_from_mem(void *data, unsigned int len); |
||||
|
||||
/** Validate an X509 certificate chain, with the chain being located in a directory
|
||||
@param[in] tsdir The path to the trust store directory |
||||
@param[in] certpath The path to the X509 certificate to be validated. |
||||
@return 0 for success, -1 for error or invalid certificate. |
||||
*/ |
||||
int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath); |
||||
|
||||
/** Validate an X509 certificate chain with support for a CRL
|
||||
@param[in] authorities A NULL-terminated array of strings that hold the path of the CA's X509 certificate |
||||
@param[in] crlpath An optional path to the CRL file. NULL if no CRL. |
||||
@param[in] certpath The path to the X509 certificate to be validated. |
||||
@return 0 for success, -1 for error or invalid certificate. |
||||
*/ |
||||
int cl_validate_certificate_chain(char **authorities, char *crlpath, char *certpath); |
||||
|
||||
/** Load an X509 certificate from a file
|
||||
@param[in] certpath The path to the X509 certificate |
||||
*/ |
||||
X509 *cl_load_cert(const char *certpath); |
||||
|
||||
/** Parse an ASN1_TIME object
|
||||
@param[in] timeobj The ASN1_TIME object |
||||
@return A pointer to a (struct tm). Adjusted for time zone and daylight savings time. |
||||
*/ |
||||
struct tm *cl_ASN1_GetTimeT(ASN1_TIME *timeobj); |
||||
|
||||
/** Load a CRL file into an X509_CRL object
|
||||
@param[in] file The path to the CRL |
||||
@return A pointer to an X509_CRL object or NULL on error. |
||||
*/ |
||||
X509_CRL *cl_load_crl(const char *timeobj); |
||||
|
||||
/** Sign data with a key stored on disk
|
||||
@param[in] keypath The path to the RSA private key |
||||
@param[in] alg The hash/signature algorithm to use |
||||
@param[in] hash The hash to sign |
||||
@param[out] olen A pointer that stores the size of the signature |
||||
@param[in] Whether or not to base64-encode the signature. 1 for yes, 0 for no. |
||||
@return The generated signature |
||||
*/ |
||||
unsigned char *cl_sign_data_keyfile(char *keypath, char *alg, unsigned char *hash, unsigned int *olen, int encode); |
||||
|
||||
/** Sign data with an RSA private key object
|
||||
@param[in] pkey The RSA private key object |
||||
@param[in] alg The hash/signature algorithm to use |
||||
@param[in] hash The hash to sign |
||||
@param[out] olen A pointer that stores the size of the signature |
||||
@param[in] Whether or not to base64-encode the signature. 1 for yes, 0 for no. |
||||
@return The generated signature |
||||
*/ |
||||
unsigned char *cl_sign_data(EVP_PKEY *pkey, char *alg, unsigned char *hash, unsigned int *olen, int encode); |
||||
|
||||
/** Sign a file with an RSA private key object
|
||||
@param[in] fd The file descriptor |
||||
@param[in] pkey The RSA private key object |
||||
@param[in] alg The hash/signature algorithm to use |
||||
@param[out] olen A pointer that stores the size of the signature |
||||
@param[in] encode Whether or not to base64-encode the signature. 1 for yes, 0 for no. |
||||
*/ |
||||
unsigned char *cl_sign_file_fd(int fd, EVP_PKEY *pkey, char *alg, unsigned int *olen, int encode); |
||||
|
||||
/** Sign a file with an RSA private key object
|
||||
@param[in] fp A pointer to a FILE object |
||||
@param[in] pkey The RSA private key object |
||||
@param[in] alg The hash/signature algorithm to use |
||||
@param[out] olen A pointer that stores the size of the signature |
||||
@param[in] encode Whether or not to base64-encode the signature. 1 for yes, 0 for no. |
||||
*/ |
||||
unsigned char *cl_sign_file_fp(FILE *fp, EVP_PKEY *pkey, char *alg, unsigned int *olen, int encode); |
||||
|
||||
/** Get the Private Key stored on disk
|
||||
* @param[in] keypath The path on disk where the private key is stored |
||||
* @return A pointer to the EVP_PKEY object that contains the private key in memory |
||||
*/ |
||||
EVP_PKEY *cl_get_pkey_file(char *keypath); |
||||
|
||||
/**
|
||||
* @} |
||||
*/ |
||||
|
||||
#endif |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue