merged the modularization branch (credentials) back to trunk
This commit is contained in:
@@ -9,43 +9,37 @@ else
|
||||
endif
|
||||
|
||||
libstrongswan_la_SOURCES += \
|
||||
credential_store.h \
|
||||
library.c library.h \
|
||||
chunk.c chunk.h \
|
||||
debug.c debug.h \
|
||||
enum.c enum.h \
|
||||
settings.h settings.c \
|
||||
printf_hook.c printf_hook.h \
|
||||
asn1/asn1.c asn1/asn1.h \
|
||||
asn1/oid.c asn1/oid.h \
|
||||
asn1/pem.c asn1/pem.h \
|
||||
asn1/ttodata.c asn1/ttodata.h \
|
||||
crypto/ac.c crypto/ac.h \
|
||||
crypto/ca.c crypto/ca.h \
|
||||
crypto/certinfo.c crypto/certinfo.h \
|
||||
crypto/crl.c crypto/crl.h \
|
||||
crypto/crypters/crypter.c crypto/crypters/crypter.h \
|
||||
crypto/crypters/aes_cbc_crypter.c crypto/crypters/aes_cbc_crypter.h \
|
||||
crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \
|
||||
crypto/diffie_hellman.c crypto/diffie_hellman.h \
|
||||
crypto/hashers/hasher.h crypto/hashers/hasher.c \
|
||||
crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
|
||||
crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \
|
||||
crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \
|
||||
crypto/hmac.c crypto/hmac.h \
|
||||
crypto/ietf_attr_list.c crypto/ietf_attr_list.h \
|
||||
crypto/ocsp.c crypto/ocsp.h \
|
||||
crypto/pkcs7.c crypto/pkcs7.h \
|
||||
crypto/pkcs9.c crypto/pkcs9.h \
|
||||
crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \
|
||||
crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \
|
||||
crypto/prfs/prf.c crypto/prfs/prf.h \
|
||||
crypto/prf_plus.h crypto/prf_plus.c \
|
||||
crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \
|
||||
crypto/rsa/rsa_public_key.h crypto/rsa/rsa_public_key.c \
|
||||
crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \
|
||||
crypto/signers/signer.c crypto/signers/signer.h \
|
||||
crypto/x509.c crypto/x509.h \
|
||||
utils/fetcher.c utils/fetcher.h \
|
||||
crypto/diffie_hellman.c crypto/diffie_hellman.h \
|
||||
crypto/crypto_factory.c crypto/crypto_factory.h \
|
||||
credentials/credential_factory.c credentials/credential_factory.h \
|
||||
credentials/builder.c credentials/builder.h \
|
||||
credentials/keys/private_key.c credentials/keys/private_key.h \
|
||||
credentials/keys/public_key.c credentials/keys/public_key.h \
|
||||
credentials/keys/shared_key.c credentials/keys/shared_key.h \
|
||||
credentials/certificates/certificate.c credentials/certificates/certificate.h \
|
||||
credentials/certificates/x509.h credentials/certificates/x509.c \
|
||||
credentials/certificates/crl.h credentials/certificates/crl.c \
|
||||
credentials/certificates/ocsp_request.h credentials/certificates/ocsp_request.c \
|
||||
credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
|
||||
fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
|
||||
database/database.h database/database_factory.h database/database_factory.c \
|
||||
utils.h utils.c \
|
||||
utils/host.c utils/host.h \
|
||||
utils/identification.c utils/identification.h \
|
||||
utils/iterator.h \
|
||||
@@ -54,28 +48,22 @@ utils/lexparser.c utils/lexparser.h \
|
||||
utils/linked_list.c utils/linked_list.h \
|
||||
utils/enumerator.c utils/enumerator.h \
|
||||
utils/optionsfrom.c utils/optionsfrom.h \
|
||||
utils/randomizer.c utils/randomizer.h
|
||||
utils/randomizer.c utils/randomizer.h \
|
||||
utils/mutex.c utils/mutex.h \
|
||||
plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h
|
||||
|
||||
if USE_INTEGRITY_TEST
|
||||
libstrongswan_la_SOURCES += \
|
||||
fips/fips_canister_end.c
|
||||
endif
|
||||
|
||||
libstrongswan_la_LIBADD = -lgmp -lpthread
|
||||
libstrongswan_la_LIBADD = -lpthread -ldl
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
AM_CFLAGS =
|
||||
|
||||
if USE_LEAK_DETECTIVE
|
||||
libstrongswan_la_LIBADD += -ldl
|
||||
AM_CFLAGS = -DLEAK_DETECTIVE
|
||||
endif
|
||||
|
||||
if USE_LIBCURL
|
||||
libstrongswan_la_LIBADD += -lcurl
|
||||
endif
|
||||
|
||||
if USE_LIBLDAP
|
||||
libstrongswan_la_LIBADD += -lldap -llber
|
||||
AM_CFLAGS += -DLEAK_DETECTIVE
|
||||
endif
|
||||
|
||||
EXTRA_DIST = asn1/oid.txt asn1/oid.pl
|
||||
@@ -88,6 +76,65 @@ asn1/oid.c : asn1/oid.txt asn1/oid.pl
|
||||
asn1/oid.h : asn1/oid.txt asn1/oid.pl
|
||||
cd asn1 && $(PERL) oid.pl
|
||||
|
||||
|
||||
# build plugins with their own Makefile
|
||||
#######################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
if USE_AES
|
||||
SUBDIRS += plugins/aes
|
||||
endif
|
||||
|
||||
if USE_DES
|
||||
SUBDIRS += plugins/des
|
||||
endif
|
||||
|
||||
if USE_MD5
|
||||
SUBDIRS += plugins/md5
|
||||
endif
|
||||
|
||||
if USE_SHA1
|
||||
SUBDIRS += plugins/sha1
|
||||
endif
|
||||
|
||||
if USE_SHA2
|
||||
SUBDIRS += plugins/sha2
|
||||
endif
|
||||
|
||||
if USE_FIPS_PRF
|
||||
SUBDIRS += plugins/fips_prf
|
||||
endif
|
||||
|
||||
if USE_GMP
|
||||
SUBDIRS += plugins/gmp
|
||||
endif
|
||||
|
||||
if USE_HMAC
|
||||
SUBDIRS += plugins/hmac
|
||||
endif
|
||||
|
||||
if USE_X509
|
||||
SUBDIRS += plugins/x509
|
||||
endif
|
||||
|
||||
if USE_CURL
|
||||
SUBDIRS += plugins/curl
|
||||
endif
|
||||
|
||||
if USE_LDAP
|
||||
SUBDIRS += plugins/ldap
|
||||
endif
|
||||
|
||||
if USE_MYSQL
|
||||
SUBDIRS += plugins/mysql
|
||||
endif
|
||||
|
||||
if USE_SQLITE
|
||||
SUBDIRS += plugins/sqlite
|
||||
endif
|
||||
|
||||
|
||||
if USE_INTEGRITY_TEST
|
||||
# build fips_signer which in turn builds fips_signature.h
|
||||
#########################################################
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
/**
|
||||
* @file asn1.c
|
||||
*
|
||||
* @brief Simple ASN.1 parser
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Will
|
||||
* Copyright (C) 2000-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -21,7 +13,7 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -833,20 +825,6 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
|
||||
return construct;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a MP integer into a DER coded ASN.1 object
|
||||
*/
|
||||
chunk_t asn1_integer_from_mpz(const mpz_t value)
|
||||
{
|
||||
size_t bits = mpz_sizeinbase(value, 2); /* size in bits */
|
||||
chunk_t n;
|
||||
|
||||
n.len = 1 + bits / 8; /* size in bytes */
|
||||
n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
|
||||
|
||||
return asn1_wrap(ASN1_INTEGER, "m", n);
|
||||
}
|
||||
|
||||
/**
|
||||
* ASN.1 definition of time
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file asn1.h
|
||||
*
|
||||
* @brief Simple ASN.1 parser
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Will
|
||||
* Copyright (C) 2000-2008 Andreas Steffen
|
||||
@@ -21,11 +14,16 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup asn1 asn1
|
||||
* @{ @ingroup asn1
|
||||
*/
|
||||
|
||||
#ifndef _ASN1_H
|
||||
#define _ASN1_H
|
||||
#ifndef ASN1_H_
|
||||
#define ASN1_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <gmp.h>
|
||||
@@ -35,9 +33,7 @@
|
||||
|
||||
|
||||
/**
|
||||
* @brief Definition of some primitive ASN1 types
|
||||
*
|
||||
* @ingroup asn1
|
||||
* Definition of some primitive ASN1 types
|
||||
*/
|
||||
typedef enum {
|
||||
ASN1_EOC = 0x00,
|
||||
@@ -87,7 +83,6 @@ typedef enum {
|
||||
} asn1_t;
|
||||
|
||||
/* Definition of ASN1 flags */
|
||||
|
||||
#define ASN1_NONE 0x00
|
||||
#define ASN1_DEF 0x01
|
||||
#define ASN1_OPT 0x02
|
||||
@@ -100,7 +95,6 @@ typedef enum {
|
||||
#define ASN1_INVALID_LENGTH 0xffffffff
|
||||
|
||||
/* definition of an ASN.1 object */
|
||||
|
||||
typedef struct {
|
||||
u_int level;
|
||||
const u_char *name;
|
||||
@@ -141,9 +135,8 @@ extern bool is_asn1(chunk_t blob);
|
||||
|
||||
extern void code_asn1_length(size_t length, chunk_t *code);
|
||||
extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
|
||||
extern chunk_t asn1_integer_from_mpz(const mpz_t value);
|
||||
extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
|
||||
extern chunk_t asn1_bitstring(const char *mode, chunk_t content);
|
||||
extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
|
||||
|
||||
#endif /* _ASN1_H */
|
||||
#endif /* ASN1_H_ @}*/
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -95,10 +95,16 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
|
||||
u_int8_t padding, *last_padding_pos, *first_padding_pos;
|
||||
|
||||
if (passphrase == NULL || passphrase->len == 0)
|
||||
{
|
||||
return "missing passphrase";
|
||||
}
|
||||
|
||||
/* build key from passphrase and IV */
|
||||
hasher = hasher_create(HASH_MD5);
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
return "MD5 hasher not supported";
|
||||
}
|
||||
hash.len = hasher->get_hash_size(hasher);
|
||||
hash.ptr = alloca(hash.len);
|
||||
hasher->get_hash(hasher, *passphrase, NULL);
|
||||
@@ -115,7 +121,7 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
|
||||
hasher->destroy(hasher);
|
||||
|
||||
/* decrypt blob */
|
||||
crypter = crypter_create(alg, key_size);
|
||||
crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
|
||||
crypter->set_key(crypter, key);
|
||||
if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS)
|
||||
{
|
||||
@@ -310,8 +316,8 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
|
||||
/* load a coded key or certificate file with autodetection
|
||||
* of binary DER or base64 PEM ASN.1 formats and armored PGP format
|
||||
*/
|
||||
bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
|
||||
const char *type, chunk_t *blob, bool *pgp)
|
||||
bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
|
||||
chunk_t *blob, bool *pgp)
|
||||
{
|
||||
err_t ugh = NULL;
|
||||
|
||||
@@ -326,7 +332,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
|
||||
blob->ptr = malloc(blob->len);
|
||||
bytes = fread(blob->ptr, 1, blob->len, fd);
|
||||
fclose(fd);
|
||||
DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes);
|
||||
DBG2(" loading '%s' (%d bytes)", filename, bytes);
|
||||
|
||||
*pgp = FALSE;
|
||||
|
||||
@@ -364,7 +370,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(" could not open %s file '%s'", type, filename);
|
||||
DBG1(" reading file '%s' failed", filename);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp);
|
||||
|
||||
bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
|
||||
const char *type, chunk_t *blob, bool *pgp);
|
||||
bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
|
||||
chunk_t *blob, bool *pgp);
|
||||
|
||||
#endif /*PEM_H_*/
|
||||
#endif /*PEM_H_ @} */
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||
* License for more details.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "ttodata.h"
|
||||
@@ -34,7 +36,7 @@ static const char *badch(const char *, int, char *, size_t);
|
||||
#define BADOFF(code) (BADCH0-(code))
|
||||
|
||||
/**
|
||||
* @brief convert text to data, with verbose error reports
|
||||
* convert text to data, with verbose error reports
|
||||
*
|
||||
* If some of this looks slightly odd, it's because it has changed
|
||||
* repeatedly (from the original atodata()) without a major rewrite.
|
||||
@@ -197,7 +199,7 @@ const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ttodata - convert text to data
|
||||
* ttodata - convert text to data
|
||||
*
|
||||
* @param src
|
||||
* @param srclen 0 means apply strlen()
|
||||
@@ -214,7 +216,7 @@ const char *ttodata(const char *src, size_t srclen, int base, char *dst, size_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief atodata - convert ASCII to data
|
||||
* atodata - convert ASCII to data
|
||||
*
|
||||
* backward-compatibility interface
|
||||
*
|
||||
@@ -234,7 +236,7 @@ size_t atodata(const char *src, size_t srclen, char *dst, size_t dstlen)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief atobytes - convert ASCII to data bytes
|
||||
* atobytes - convert ASCII to data bytes
|
||||
*
|
||||
* another backward-compatibility interface
|
||||
*/
|
||||
@@ -244,7 +246,7 @@ const char *atobytes(const char *src, size_t srclen, char *dst, size_t dstlen, s
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unhex - convert two ASCII hex digits to byte
|
||||
* unhex - convert two ASCII hex digits to byte
|
||||
*
|
||||
* @param src known to be full length
|
||||
* @param dstnumber of result bytes, or error code
|
||||
@@ -290,7 +292,7 @@ static int unhex(const char *src, char *dst, size_t dstlen)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unb64 - convert four ASCII base64 digits to three bytes
|
||||
* unb64 - convert four ASCII base64 digits to three bytes
|
||||
*
|
||||
* Note that a base64 digit group is padded out with '=' if it represents
|
||||
* less than three bytes: one byte is dd==, two is ddd=, three is dddd.
|
||||
@@ -368,7 +370,7 @@ static int unb64(const char *src, char *dst, size_t dstlen)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief untext - convert one ASCII character to byte
|
||||
* untext - convert one ASCII character to byte
|
||||
*
|
||||
* @param src known to be full length
|
||||
* @param dst
|
||||
@@ -386,7 +388,7 @@ static int untext(const char *src, char *dst, size_t dstlen)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief badch - produce a nice complaint about an unknown character
|
||||
* badch - produce a nice complaint about an unknown character
|
||||
*
|
||||
* If the compiler complains that the array bigenough[] has a negative
|
||||
* size, that means the TTODATAV_BUF constant has been set too small.
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
|
||||
|
||||
|
||||
#endif /* TTODATA_H_ */
|
||||
#endif /* TTODATA_H_ @} */
|
||||
|
||||
+23
-74
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file chunk.c
|
||||
*
|
||||
* @brief Pointer/lenght abstraction and its functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -356,82 +351,22 @@ bool chunk_equals_or_null(chunk_t a, chunk_t b)
|
||||
return a.len == b.len && memeq(a.ptr, b.ptr, a.len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of bytes per line to dump raw data
|
||||
*/
|
||||
#define BYTES_PER_LINE 16
|
||||
|
||||
/**
|
||||
* output handler in printf() for byte ranges
|
||||
*/
|
||||
static int print_bytes(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
char *bytes = *((void**)(args[0]));
|
||||
int len = *((size_t*)(args[1]));
|
||||
|
||||
char buffer[BYTES_PER_LINE * 3];
|
||||
char ascii_buffer[BYTES_PER_LINE + 1];
|
||||
char *buffer_pos = buffer;
|
||||
char *bytes_pos = bytes;
|
||||
char *bytes_roof = bytes + len;
|
||||
int line_start = 0;
|
||||
int i = 0;
|
||||
int written = 0;
|
||||
|
||||
written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
|
||||
|
||||
while (bytes_pos < bytes_roof)
|
||||
{
|
||||
*buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
|
||||
*buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF];
|
||||
|
||||
ascii_buffer[i++] =
|
||||
(*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
|
||||
|
||||
if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE)
|
||||
{
|
||||
int padding = 3 * (BYTES_PER_LINE - i);
|
||||
int written;
|
||||
|
||||
while (padding--)
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
*buffer_pos++ = '\0';
|
||||
ascii_buffer[i] = '\0';
|
||||
|
||||
written += fprintf(stream, "\n%4d: %s %s",
|
||||
line_start, buffer, ascii_buffer);
|
||||
|
||||
|
||||
buffer_pos = buffer;
|
||||
line_start += BYTES_PER_LINE;
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer_pos++ = ' ';
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* output handler in printf() for chunks
|
||||
*/
|
||||
static int print_chunk(FILE *stream, const struct printf_info *info,
|
||||
static int chunk_print(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
chunk_t *chunk = *((chunk_t**)(args[0]));
|
||||
bool first = TRUE;
|
||||
chunk_t copy = *chunk;
|
||||
int written = 0;
|
||||
printf_hook_functions_t mem = mem_get_printf_hooks();
|
||||
|
||||
if (!info->alt)
|
||||
{
|
||||
const void *new_args[] = {&chunk->ptr, &chunk->len};
|
||||
return print_bytes(stream, info, new_args);
|
||||
return mem.print(stream, info, new_args);
|
||||
}
|
||||
|
||||
while (copy.len > 0)
|
||||
@@ -451,10 +386,24 @@ static int print_chunk(FILE *stream, const struct printf_info *info,
|
||||
}
|
||||
|
||||
/**
|
||||
* register printf() handlers
|
||||
* arginfo handler for printf() mem ranges
|
||||
*/
|
||||
static void __attribute__ ((constructor))print_register()
|
||||
static int chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes)
|
||||
{
|
||||
register_printf_function(PRINTF_CHUNK, print_chunk, arginfo_ptr);
|
||||
register_printf_function(PRINTF_BYTES, print_bytes, arginfo_ptr_int);
|
||||
if (n > 0)
|
||||
{
|
||||
argtypes[0] = PA_POINTER;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* return printf hook functions for a chunk
|
||||
*/
|
||||
printf_hook_functions_t chunk_get_printf_hooks()
|
||||
{
|
||||
printf_hook_functions_t hooks = {chunk_print, chunk_arginfo};
|
||||
|
||||
return hooks;
|
||||
}
|
||||
|
||||
|
||||
+20
-11
@@ -1,12 +1,5 @@
|
||||
/**
|
||||
* @file chunk.h
|
||||
*
|
||||
* @brief Pointer/length abstraction and its functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup chunk chunk
|
||||
* @{ @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
#ifndef CHUNK_H_
|
||||
@@ -26,8 +26,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct chunk_t chunk_t;
|
||||
|
||||
@@ -41,6 +40,8 @@ struct chunk_t {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* A { NULL, 0 }-chunk handy for initialization.
|
||||
*/
|
||||
@@ -161,4 +162,12 @@ bool chunk_equals(chunk_t a, chunk_t b);
|
||||
*/
|
||||
bool chunk_equals_or_null(chunk_t a, chunk_t b);
|
||||
|
||||
#endif /* CHUNK_H_ */
|
||||
/**
|
||||
* Get printf hooks for a chunk.
|
||||
*
|
||||
* Arguments are:
|
||||
* chunk_t *chunk
|
||||
*/
|
||||
printf_hook_functions_t chunk_get_printf_hooks();
|
||||
|
||||
#endif /* CHUNK_H_ @}*/
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
/**
|
||||
* @file credential_store.h
|
||||
*
|
||||
* @brief Interface credential_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CREDENTIAL_STORE_H_
|
||||
#define CREDENTIAL_STORE_H_
|
||||
|
||||
typedef struct credential_store_t credential_store_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/x509.h>
|
||||
#include <crypto/ca.h>
|
||||
#include <crypto/rsa/rsa_private_key.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief The interface for a credential_store backend.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - stroke_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct credential_store_t {
|
||||
|
||||
/**
|
||||
* @brief Returns the secret shared by two specific IDs.
|
||||
*
|
||||
* The returned chunk must be destroyed by the caller after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id my ID identifiying the secret.
|
||||
* @param other_id peer ID identifying the secret.
|
||||
* @param[out] secret the pre-shared secret will be written there.
|
||||
* @return
|
||||
* - NOT_FOUND if no preshared secrets for specific ID could be found
|
||||
* - SUCCESS
|
||||
*
|
||||
*/
|
||||
status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id,
|
||||
identification_t *other_id, chunk_t *shared_key);
|
||||
|
||||
/**
|
||||
* @brief Returns the EAP secret for two specified IDs.
|
||||
*
|
||||
* The returned chunk must be destroyed by the caller after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id my ID identifiying the secret.
|
||||
* @param other_id peer ID identifying the secret.
|
||||
* @param[out] eap_key the EAP secret will be written here
|
||||
* @return
|
||||
* - NOT_FOUND if no preshared secrets for specific ID could be found
|
||||
* - SUCCESS
|
||||
*
|
||||
*/
|
||||
status_t (*get_eap_key) (credential_store_t *this, identification_t *my_id,
|
||||
identification_t *other_id, chunk_t *eap_key);
|
||||
|
||||
/**
|
||||
* @brief Returns the RSA public key of a specific ID.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param id identification_t object identifiying the key.
|
||||
* @return public key, or NULL if not found
|
||||
*/
|
||||
rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id);
|
||||
|
||||
/**
|
||||
* @brief Is there a matching RSA private key belonging to an RSA public key?
|
||||
*
|
||||
* @param this calling object
|
||||
* @param pubkey public key
|
||||
* @return TRUE if matching private key was found
|
||||
*/
|
||||
bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey);
|
||||
|
||||
/**
|
||||
* @brief Returns the certificate of a specific ID.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param id identification_t object identifiying the cert.
|
||||
* @return certificate, or NULL if not found
|
||||
*/
|
||||
x509_t* (*get_certificate) (credential_store_t *this, identification_t *id);
|
||||
|
||||
/**
|
||||
* @brief Returns the auth certificate of a specific subject distinguished name.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param auth_flags set of allowed authority types
|
||||
* @param id identification_t object identifiying the cacert.
|
||||
* @return certificate, or NULL if not found
|
||||
*/
|
||||
x509_t* (*get_auth_certificate) (credential_store_t *this, u_int auth_flags, identification_t *id);
|
||||
|
||||
/**
|
||||
* @brief Returns the ca certificate of a specific keyID.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param keyid identification_t object identifiying the cacert.
|
||||
* @return certificate, or NULL if not found
|
||||
*/
|
||||
x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid);
|
||||
|
||||
/**
|
||||
* @brief Returns the issuing ca of a given certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert certificate for which issuer ca info is required
|
||||
* @return ca info, or NULL if not found
|
||||
*/
|
||||
ca_info_t* (*get_issuer) (credential_store_t *this, x509_t* cert);
|
||||
|
||||
/**
|
||||
* @brief RSA private key belonging to an RSA public key
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param pubkey public key used to find the matching private key
|
||||
* @param hash_algorithm hash algorithm to be used for signature
|
||||
* @param data data block to be signed
|
||||
* @param signature signature to be returned
|
||||
* @return status of the signature process - SUCCESS if successful
|
||||
*/
|
||||
status_t (*rsa_signature) (credential_store_t *this, rsa_public_key_t *pubkey, hash_algorithm_t hash_algorithm,
|
||||
chunk_t data, chunk_t *signature);
|
||||
|
||||
/**
|
||||
* @brief Verify an RSA signature given the ID of the signer
|
||||
*
|
||||
* @param this calling object
|
||||
* @param hash hash value to be verified.
|
||||
* @param sig signature to be verified.
|
||||
* @param id identification_t object identifiying the signer.
|
||||
* @param issuer_p issuer of the signer's certificate (if not self-signed).
|
||||
* @return status of the verification - SUCCESS if successful
|
||||
*/
|
||||
status_t (*verify_signature) (credential_store_t *this, chunk_t hash, chunk_t sig, identification_t *id,
|
||||
ca_info_t **issuer_p);
|
||||
|
||||
/**
|
||||
* @brief Verify an X.509 certificate up to trust anchor without any status checks
|
||||
*
|
||||
* @param this calling object
|
||||
* @param label label characterizing the certificate to be verified
|
||||
* @param cert certificate to be verified
|
||||
* @return TRUE if trusted
|
||||
*/
|
||||
bool (*is_trusted) (credential_store_t *this, const char *label, x509_t *cert);
|
||||
|
||||
/**
|
||||
* @brief Verify an X.509 certificate up to trust anchor including status checks
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert certificate to be verified
|
||||
* @param found found a certificate copy in the credential store
|
||||
* @return TRUE if valid, trusted, and current status is good
|
||||
*/
|
||||
bool (*verify) (credential_store_t *this, x509_t *cert, bool *found);
|
||||
|
||||
/**
|
||||
* @brief If an end certificate does not already exists in the credential store then add it.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert certificate to be added
|
||||
* @return pointer to the added or already existing certificate
|
||||
*/
|
||||
x509_t* (*add_end_certificate) (credential_store_t *this, x509_t *cert);
|
||||
|
||||
/**
|
||||
* @brief If an authority certificate does not already exists in the credential store then add it.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert authority certificate to be added
|
||||
* @param auth_flag authority flags to add to the certificate
|
||||
* @return pointer to the added or already existing certificate
|
||||
*/
|
||||
x509_t* (*add_auth_certificate) (credential_store_t *this, x509_t *cert, u_int auth_flag);
|
||||
|
||||
/**
|
||||
* @brief If a ca info record does not already exists in the credential store then add it.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param ca_info ca info record to be added
|
||||
* @return pointer to the added or already existing ca_info_t record
|
||||
*/
|
||||
ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
|
||||
|
||||
/**
|
||||
* @brief Release a ca info record with a given name.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param name name of the ca info record to be released
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - NOT_FOUND
|
||||
*/
|
||||
status_t (*release_ca_info) (credential_store_t *this, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all end certificates.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator
|
||||
*/
|
||||
iterator_t* (*create_cert_iterator) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all authority certificates.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator
|
||||
*/
|
||||
iterator_t* (*create_auth_cert_iterator) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all CA info records
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator
|
||||
*/
|
||||
iterator_t* (*create_cainfo_iterator) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator over all attribute certificates.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator
|
||||
*/
|
||||
iterator_t* (*create_acert_iterator) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads ca certificates from a default directory.
|
||||
*
|
||||
* Certificates in both DER and PEM format are accepted
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*load_ca_certificates) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads authorization authority certificates from a default directory.
|
||||
*
|
||||
* Certificates in both DER and PEM format are accepted
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*load_aa_certificates) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads attribute certificates from a default directory.
|
||||
*
|
||||
* Certificates in both DER and PEM format are accepted
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*load_attr_certificates) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads ocsp certificates from a default directory.
|
||||
*
|
||||
* Certificates in both DER and PEM format are accepted
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*load_ocsp_certificates) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads CRLs from a default directory.
|
||||
*
|
||||
* Certificates in both DER and PEM format are accepted
|
||||
*
|
||||
* @param this calling object
|
||||
* @param path directory to load crls from
|
||||
*/
|
||||
void (*load_crls) (credential_store_t *this);
|
||||
|
||||
/**
|
||||
* @brief Loads secrets in ipsec.secrets
|
||||
*
|
||||
* RSA private key files can be either in DER or PEM format
|
||||
* Optional encryption with a passphrase supported
|
||||
*
|
||||
* @param this calling object
|
||||
* @param reload are the secrets to be reloaded
|
||||
*/
|
||||
void (*load_secrets) (credential_store_t *this, bool reload);
|
||||
|
||||
/**
|
||||
* @brief Destroys a credential_store_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (credential_store_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a credential_store_t instance.
|
||||
*
|
||||
* @param strict enforce a strict crl policy
|
||||
* @return credential store instance.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
credential_store_t *credential_store_create(bool strict);
|
||||
|
||||
|
||||
#endif /*CREDENTIAL_STORE_H_*/
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "builder.h"
|
||||
|
||||
ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END,
|
||||
"BUILD_BLOB_ASN1_DER",
|
||||
"BUILD_KEY_SIZE",
|
||||
"BUILD_SIGNING_KEY",
|
||||
"BUILD_SIGNING_CERT",
|
||||
"BUILD_PUBLIC_KEY",
|
||||
"BUILD_SUBJECT",
|
||||
"BUILD_SUBJECT_ALTNAME",
|
||||
"BUILD_ISSUER",
|
||||
"BUILD_ISSUER_ALTNAME",
|
||||
"BUILD_CA_CERT",
|
||||
"BUILD_CERT",
|
||||
"BUILD_END",
|
||||
);
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup builder builder
|
||||
* @{ @ingroup credentials
|
||||
*/
|
||||
|
||||
#ifndef BUILDER_H_
|
||||
#define BUILDER_H_
|
||||
|
||||
typedef struct builder_t builder_t;
|
||||
typedef enum builder_part_t builder_part_t;
|
||||
|
||||
/**
|
||||
* Constructor function which creates a new builder instance.
|
||||
*
|
||||
* @param subtype constructor specific subtype, e.g. certificate_type_t
|
||||
* @return builder to construct a instance of type
|
||||
*/
|
||||
typedef builder_t* (*builder_constructor_t)(int subtype);
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Parts to build credentials from.
|
||||
*/
|
||||
enum builder_part_t {
|
||||
/** DER encoded ASN1 blob, argument is a chunk_t */
|
||||
BUILD_BLOB_ASN1_DER,
|
||||
/** key size in bits, as used for key generation, as u_int */
|
||||
BUILD_KEY_SIZE,
|
||||
/** private key to use for signing, private_key_t* */
|
||||
BUILD_SIGNING_KEY,
|
||||
/** certificate used for signing, certificate_t* */
|
||||
BUILD_SIGNING_CERT,
|
||||
/** public key to include, public_key_t* */
|
||||
BUILD_PUBLIC_KEY,
|
||||
/** subject for e.g. certificates, identification_t* */
|
||||
BUILD_SUBJECT,
|
||||
/** additional subject name, identification_t* */
|
||||
BUILD_SUBJECT_ALTNAME,
|
||||
/** issuer for e.g. certificates, identification_t* */
|
||||
BUILD_ISSUER,
|
||||
/** additional issuer name, identification_t* */
|
||||
BUILD_ISSUER_ALTNAME,
|
||||
/** a CA certificate, certificate_t* */
|
||||
BUILD_CA_CERT,
|
||||
/** a certificcate, certificate_t* */
|
||||
BUILD_CERT,
|
||||
/** end of variable argument builder list */
|
||||
BUILD_END,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum names for build_part_t
|
||||
*/
|
||||
extern enum_name_t *builder_part_names;
|
||||
|
||||
/**
|
||||
* Credential construction API.
|
||||
*
|
||||
* The builder allows the construction of credentials in a generic and
|
||||
* flexible way.
|
||||
*/
|
||||
struct builder_t {
|
||||
|
||||
/**
|
||||
* Add a part to the construct.
|
||||
*
|
||||
* Any added parts get owned by the builder/construct, so clone/refcount
|
||||
* them if needed.
|
||||
*
|
||||
* @param part kind of part
|
||||
* @param ... part specific variable argument
|
||||
*/
|
||||
void (*add)(builder_t *this, builder_part_t part, ...);
|
||||
|
||||
/**
|
||||
* Build the construct with all supplied parts.
|
||||
*
|
||||
* Once build() is called, the builder gets destroyed.
|
||||
*
|
||||
* @return specific interface, as requested with constructor.
|
||||
*/
|
||||
void* (*build)(builder_t *this);
|
||||
};
|
||||
|
||||
#endif /* BUILDER_H_ @}*/
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "certificate.h"
|
||||
|
||||
#include <credentials/certificates/x509.h>
|
||||
|
||||
ENUM(certificate_type_names, CERT_ANY, CERT_PGP,
|
||||
"ANY",
|
||||
"X509",
|
||||
"X509_CRL",
|
||||
"X509_OCSP_REQUEST",
|
||||
"X509_OCSP_RESPONSE",
|
||||
"X509_AC",
|
||||
"X509_CHAIN",
|
||||
"TRUSTED_PUBKEY",
|
||||
"PGP",
|
||||
);
|
||||
|
||||
ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED,
|
||||
"GOOD",
|
||||
"REVOKED",
|
||||
"FAILED",
|
||||
"SKIPPED",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup certificate certificate
|
||||
* @{ @ingroup certificates
|
||||
*/
|
||||
|
||||
#ifndef CERTIFICATE_H_
|
||||
#define CERTIFICATE_H_
|
||||
|
||||
typedef struct certificate_t certificate_t;
|
||||
typedef enum certificate_type_t certificate_type_t;
|
||||
typedef enum cert_validation_t cert_validation_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/identification.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* Kind of a certificate_t
|
||||
*/
|
||||
enum certificate_type_t {
|
||||
/** just any certificate */
|
||||
CERT_ANY,
|
||||
/** X.509 certificate */
|
||||
CERT_X509,
|
||||
/** X.509 certificate revocation list */
|
||||
CERT_X509_CRL,
|
||||
/** X.509 online certificate status protocol request */
|
||||
CERT_X509_OCSP_REQUEST,
|
||||
/** X.509 online certificate status protocol response */
|
||||
CERT_X509_OCSP_RESPONSE,
|
||||
/** X.509 attribute certificate */
|
||||
CERT_X509_AC,
|
||||
/** trusted, preinstalled public key */
|
||||
CERT_TRUSTED_PUBKEY,
|
||||
/** PGP certificate */
|
||||
CERT_PGP,
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names for certificate_type_t
|
||||
*/
|
||||
extern enum_name_t *certificate_type_names;
|
||||
|
||||
/**
|
||||
* Result of a certificate validation.
|
||||
*/
|
||||
enum cert_validation_t {
|
||||
/** certificate has been validated successfully */
|
||||
VALIDATION_GOOD,
|
||||
/** validation failed, certificate is revoked */
|
||||
VALIDATION_REVOKED,
|
||||
/* ocsp status is unknown or crl is stale */
|
||||
VALIDATION_UNKNOWN,
|
||||
/** validation process failed due to an error */
|
||||
VALIDATION_FAILED,
|
||||
/** validation has been skipped (no cdps available) */
|
||||
VALIDATION_SKIPPED,
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names for cert_validation_t
|
||||
*/
|
||||
extern enum_name_t *cert_validation_names;
|
||||
|
||||
/**
|
||||
* An abstract certificate.
|
||||
*
|
||||
* A certificate designs a subject-issuer relationship. It may have an
|
||||
* associated public key.
|
||||
*/
|
||||
struct certificate_t {
|
||||
|
||||
/**
|
||||
* Get the type of the certificate.
|
||||
*
|
||||
* @return certifcate type
|
||||
*/
|
||||
certificate_type_t (*get_type)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Get the primary subject to which this certificate belongs.
|
||||
*
|
||||
* @return subject identity
|
||||
*/
|
||||
identification_t* (*get_subject)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Check if certificate contains a subject ID.
|
||||
*
|
||||
* A certificate may contain additional subject identifiers, which are
|
||||
* not returned by get_subject (e.g. subjectAltNames)
|
||||
*
|
||||
* @param subject subject identity
|
||||
* @return matching value of best match
|
||||
*/
|
||||
id_match_t (*has_subject)(certificate_t *this, identification_t *subject);
|
||||
|
||||
/**
|
||||
* Get the issuer which signed this certificate.
|
||||
*
|
||||
* @return issuer identity
|
||||
*/
|
||||
identification_t* (*get_issuer)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Check if certificate contains an issuer ID.
|
||||
*
|
||||
* A certificate may contain additional issuer identifiers, which are
|
||||
* not returned by get_issuer (e.g. issuerAltNames)
|
||||
*
|
||||
* @param subject isser identity
|
||||
* @return matching value of best match
|
||||
*/
|
||||
id_match_t (*has_issuer)(certificate_t *this, identification_t *issuer);
|
||||
|
||||
/**
|
||||
* Check if this certificate is issued by a specific issuer.
|
||||
*
|
||||
* As signature verification is computional expensive, it is optional
|
||||
* and may be skipped. While this is not sufficient for verification
|
||||
* purposes, it is to e.g. find matching certificates.
|
||||
*
|
||||
* @param issuer issuer's certificate
|
||||
* @param checksig TRUE to verify signature, FALSE to compare issuer only
|
||||
* @return TRUE if certificate issued by issuer and trusted
|
||||
*/
|
||||
bool (*issued_by)(certificate_t *this, certificate_t *issuer, bool checksig);
|
||||
|
||||
/**
|
||||
* Get the public key associated to this certificate.
|
||||
*
|
||||
* @return newly referenced public_key, NULL if none available
|
||||
*/
|
||||
public_key_t* (*get_public_key)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Check the lifetime of the certificate.
|
||||
*
|
||||
* @param when check validity at a certain time (NULL for now)
|
||||
* @param not_before receives certificates start of lifetime
|
||||
* @param not_after receives certificates end of lifetime
|
||||
* @return TRUE if when between not_after and not_before
|
||||
*/
|
||||
bool (*get_validity)(certificate_t *this, time_t *when,
|
||||
time_t *not_before, time_t *not_after);
|
||||
|
||||
/**
|
||||
* Get the certificate in an encoded form.
|
||||
*
|
||||
* @return allocated chunk of encoded cert
|
||||
*/
|
||||
chunk_t (*get_encoding)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Check if two certificates are equal.
|
||||
*
|
||||
* @param other certificate to compair against this
|
||||
* @return TRUE if certificates are equal
|
||||
*/
|
||||
bool (*equals)(certificate_t *this, certificate_t *other);
|
||||
|
||||
/**
|
||||
* Get a new reference to the certificate.
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
certificate_t* (*get_ref)(certificate_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a certificate.
|
||||
*/
|
||||
void (*destroy)(certificate_t *this);
|
||||
};
|
||||
|
||||
#endif /* CERTIFICATE_H_ @}*/
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "crl.h"
|
||||
|
||||
ENUM(crl_reason_names, CRL_UNSPECIFIED, CRL_REMOVE_FROM_CRL,
|
||||
"unspecified",
|
||||
"key compromise",
|
||||
"ca compromise",
|
||||
"affiliation changed",
|
||||
"superseded",
|
||||
"cessation of operation",
|
||||
"certificate hold",
|
||||
"reason #7",
|
||||
"remove from crl",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup crl crl
|
||||
* @{ @ingroup certificates
|
||||
*/
|
||||
|
||||
#ifndef CRL_H_
|
||||
#define CRL_H_
|
||||
|
||||
typedef struct crl_t crl_t;
|
||||
typedef enum crl_reason_t crl_reason_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* RFC 2459 CRL reason codes
|
||||
*/
|
||||
enum crl_reason_t {
|
||||
CRL_UNSPECIFIED = 0,
|
||||
CRL_KEY_COMPROMISE = 1,
|
||||
CRL_CA_COMPROMISE = 2,
|
||||
CRL_AFFILIATION_CHANGED = 3,
|
||||
CRL_SUPERSEDED = 4,
|
||||
CRL_CESSATION_OF_OPERATON = 5,
|
||||
CRL_CERTIFICATE_HOLD = 6,
|
||||
CRL_REMOVE_FROM_CRL = 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum names for crl_reason_t
|
||||
*/
|
||||
extern enum_name_t *crl_reason_names;
|
||||
|
||||
/**
|
||||
* X509 certificate revocation list (CRL) interface definition.
|
||||
*/
|
||||
struct crl_t {
|
||||
|
||||
/**
|
||||
* Implements (parts of) the certificate_t interface
|
||||
*/
|
||||
certificate_t certificate;
|
||||
|
||||
/**
|
||||
* Is that newer than this?
|
||||
*
|
||||
* @return TRUE if newer, FALSE otherwise
|
||||
*/
|
||||
bool (*is_newer)(crl_t *this, crl_t *that);
|
||||
|
||||
/**
|
||||
* Get the CRL serial number.
|
||||
*
|
||||
* @return chunk pointing to internal crlNumber
|
||||
*/
|
||||
chunk_t (*get_serial)(crl_t *this);
|
||||
|
||||
/**
|
||||
* Get the the authorityKeyIdentifier.
|
||||
*
|
||||
* @return authKeyIdentifier as identification_t*
|
||||
*/
|
||||
identification_t* (*get_authKeyIdentifier)(crl_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all revoked certificates.
|
||||
*
|
||||
* The enumerator takes 3 pointer arguments:
|
||||
* chunk_t serial, time_t revocation_date, crl_reason_t reason
|
||||
*
|
||||
* @return enumerator over revoked certificates.
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(crl_t *this);
|
||||
|
||||
};
|
||||
|
||||
#endif /* CRL_H_ @}*/
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "ocsp_request.h"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ocsp_request ocsp_request
|
||||
* @{ @ingroup certificates
|
||||
*/
|
||||
|
||||
#ifndef OCSP_REQUEST_H_
|
||||
#define OCSP_REQUEST_H_
|
||||
|
||||
#include <credentials/certificates/certificate.h>
|
||||
|
||||
typedef struct ocsp_request_t ocsp_request_t;
|
||||
|
||||
/**
|
||||
* OCSP request message.
|
||||
*/
|
||||
struct ocsp_request_t {
|
||||
|
||||
/**
|
||||
* Implements certificiate_t interface
|
||||
*/
|
||||
certificate_t interface;
|
||||
};
|
||||
|
||||
#endif /* OCSP_REQUEST_H_ @}*/
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "ocsp_response.h"
|
||||
|
||||
ENUM(ocsp_status_names, OCSP_SUCCESSFUL, OCSP_UNAUTHORIZED,
|
||||
"successful",
|
||||
"malformed request",
|
||||
"internal error",
|
||||
"try later",
|
||||
"status #4",
|
||||
"signature required",
|
||||
"unauthorized"
|
||||
);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ocsp_response ocsp_response
|
||||
* @{ @ingroup certificates
|
||||
*/
|
||||
|
||||
#ifndef OCSP_RESPONSE_H_
|
||||
#define OCSP_RESPONSE_H_
|
||||
|
||||
#include <credentials/certificates/x509.h>
|
||||
#include <credentials/certificates/crl.h>
|
||||
|
||||
typedef struct ocsp_response_t ocsp_response_t;
|
||||
typedef enum ocsp_status_t ocsp_status_t;
|
||||
|
||||
/**
|
||||
* OCSP response status
|
||||
*/
|
||||
enum ocsp_status_t {
|
||||
OCSP_SUCCESSFUL = 0,
|
||||
OCSP_MALFORMEDREQUEST = 1,
|
||||
OCSP_INTERNALERROR = 2,
|
||||
OCSP_TRYLATER = 3,
|
||||
OCSP_SIGREQUIRED = 5,
|
||||
OCSP_UNAUTHORIZED = 6,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum names for ocsp_status_t
|
||||
*/
|
||||
extern enum_name_t *ocsp_status_names;
|
||||
|
||||
/**
|
||||
* OCSP response message.
|
||||
*/
|
||||
struct ocsp_response_t {
|
||||
|
||||
/**
|
||||
* Implements certificiate_t interface
|
||||
*/
|
||||
certificate_t certificate;
|
||||
|
||||
/**
|
||||
* Check the status of a certificate by this OCSP response.
|
||||
*
|
||||
* @param subject certificate to check status
|
||||
* @param issuer issuer certificate of subject
|
||||
* @param revocation_time receives time of revocation, if revoked
|
||||
* @param revocation_reason receives reason of revocation, if revoked
|
||||
* @param this_update creation time of revocation list
|
||||
* @param next_update exptected time of next revocation list
|
||||
* @return certificate revocation status
|
||||
*/
|
||||
cert_validation_t (*get_status)(ocsp_response_t *this,
|
||||
x509_t *subject, x509_t *issuer,
|
||||
time_t *revocation_time,
|
||||
crl_reason_t *revocation_reason,
|
||||
time_t *this_update, time_t *next_update);
|
||||
|
||||
/**
|
||||
* Create an enumerator over the contained certificates.
|
||||
*
|
||||
* @return enumerator over certificate_t*
|
||||
*/
|
||||
enumerator_t* (*create_cert_enumerator)(ocsp_response_t *this);
|
||||
};
|
||||
|
||||
#endif /* OCSP_RESPONSE_H_ @}*/
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "x509.h"
|
||||
|
||||
ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED,
|
||||
"X509_CA",
|
||||
"X509_AA",
|
||||
"X509_OCSP_SIGNER",
|
||||
"X509_SELF_SIGNED",
|
||||
);
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup x509 x509
|
||||
* @{ @ingroup certificates
|
||||
*/
|
||||
|
||||
#ifndef X509_H_
|
||||
#define X509_H_
|
||||
|
||||
#include <utils/enumerator.h>
|
||||
#include <credentials/certificates/certificate.h>
|
||||
|
||||
typedef struct x509_t x509_t;
|
||||
typedef enum x509_flag_t x509_flag_t;
|
||||
|
||||
/**
|
||||
* X.509 certificate flags.
|
||||
*/
|
||||
enum x509_flag_t {
|
||||
/** cert has CA constraint */
|
||||
X509_CA = (1<<0),
|
||||
/** cert has AA constraint */
|
||||
X509_AA = (1<<1),
|
||||
/** cert has OCSP signer constraint */
|
||||
X509_OCSP_SIGNER = (1<<2),
|
||||
/** cert belongs to an end entity */
|
||||
X509_PEER = (1<<3),
|
||||
/** cert is self-signed */
|
||||
X509_SELF_SIGNED = (1<<4),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum names for x509 flags
|
||||
*/
|
||||
extern enum_name_t *x509_flag_names;
|
||||
|
||||
/**
|
||||
* X.509 certificate interface.
|
||||
*
|
||||
* This interface adds additional methods to the certificate_t type to
|
||||
* allow further operations on these certificates.
|
||||
*/
|
||||
struct x509_t {
|
||||
|
||||
/**
|
||||
* Implements certificate_t.
|
||||
*/
|
||||
certificate_t interface;
|
||||
|
||||
/**
|
||||
* Get the flags set for this certificate.
|
||||
*
|
||||
* @return set of flags
|
||||
*/
|
||||
x509_flag_t (*get_flags)(x509_t *this);
|
||||
|
||||
/**
|
||||
* Set the flags for this certificate.
|
||||
*
|
||||
* @param flags set of flags
|
||||
*/
|
||||
void (*set_flags)(x509_t *this, x509_flag_t flags);
|
||||
|
||||
/**
|
||||
* Get the certificate serial number.
|
||||
*
|
||||
* @return chunk pointing to internal serial number
|
||||
*/
|
||||
chunk_t (*get_serial)(x509_t *this);
|
||||
|
||||
/**
|
||||
* Get the the authorityKeyIdentifier.
|
||||
*
|
||||
* @return authKeyIdentifier as identification_t*
|
||||
*/
|
||||
identification_t* (*get_authKeyIdentifier)(x509_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all subjectAltNames.
|
||||
*
|
||||
* @return enumerator over subjectAltNames as identification_t*
|
||||
*/
|
||||
enumerator_t* (*create_subjectAltName_enumerator)(x509_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all CRL URIs.
|
||||
*
|
||||
* @return enumerator over URIs as char*
|
||||
*/
|
||||
enumerator_t* (*create_crl_uri_enumerator)(x509_t *this);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all OCSP URIs.
|
||||
*
|
||||
* @return enumerator over URIs as char*
|
||||
*/
|
||||
enumerator_t* (*create_ocsp_uri_enumerator)(x509_t *this);
|
||||
};
|
||||
|
||||
#endif /* X509_H_ @}*/
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "credential_factory.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/mutex.h>
|
||||
|
||||
typedef struct private_credential_factory_t private_credential_factory_t;
|
||||
|
||||
/**
|
||||
* private data of credential_factory
|
||||
*/
|
||||
struct private_credential_factory_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
credential_factory_t public;
|
||||
|
||||
/**
|
||||
* list with entry_t
|
||||
*/
|
||||
linked_list_t *constructors;
|
||||
|
||||
/**
|
||||
* mutex to lock access to modules
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
};
|
||||
|
||||
typedef struct entry_t entry_t;
|
||||
struct entry_t {
|
||||
/** kind of credential builder */
|
||||
credential_type_t type;
|
||||
/** subtype of credential, e.g. certificate_type_t */
|
||||
int subtype;
|
||||
/** builder construction function */
|
||||
builder_constructor_t constructor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of credential_factory_t.create_builder.
|
||||
*/
|
||||
static builder_t* create_builder(private_credential_factory_t *this,
|
||||
credential_type_t type, int subtype)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
builder_t *builder = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->constructors->create_enumerator(this->constructors);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->type == type && entry->subtype == subtype)
|
||||
{
|
||||
builder = entry->constructor(subtype);
|
||||
if (builder)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_factory_t.add_builder_constructor.
|
||||
*/
|
||||
static void add_builder(private_credential_factory_t *this,
|
||||
credential_type_t type, int subtype,
|
||||
builder_constructor_t constructor)
|
||||
{
|
||||
entry_t *entry = malloc_thing(entry_t);
|
||||
|
||||
entry->type = type;
|
||||
entry->subtype = subtype;
|
||||
entry->constructor = constructor;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->constructors->insert_last(this->constructors, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_factory_t.remove_builder.
|
||||
*/
|
||||
static void remove_builder(private_credential_factory_t *this,
|
||||
builder_constructor_t constructor)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->constructors->create_enumerator(this->constructors);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->constructor == constructor)
|
||||
{
|
||||
this->constructors->remove_at(this->constructors, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_factory_t.create.
|
||||
*/
|
||||
static void* create(private_credential_factory_t *this, credential_type_t type,
|
||||
int subtype, ...)
|
||||
{
|
||||
builder_t *builder;
|
||||
builder_part_t part;
|
||||
va_list args;
|
||||
|
||||
builder = create_builder(this, type, subtype);
|
||||
if (builder)
|
||||
{
|
||||
va_start(args, subtype);
|
||||
while (TRUE)
|
||||
{
|
||||
part = va_arg(args, builder_part_t);
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_END:
|
||||
break;
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
builder->add(builder, part, va_arg(args, chunk_t));
|
||||
continue;
|
||||
case BUILD_KEY_SIZE:
|
||||
builder->add(builder, part, va_arg(args, u_int));
|
||||
continue;
|
||||
case BUILD_SIGNING_KEY:
|
||||
case BUILD_PUBLIC_KEY:
|
||||
case BUILD_SUBJECT:
|
||||
case BUILD_SUBJECT_ALTNAME:
|
||||
case BUILD_ISSUER:
|
||||
case BUILD_ISSUER_ALTNAME:
|
||||
case BUILD_SIGNING_CERT:
|
||||
case BUILD_CA_CERT:
|
||||
case BUILD_CERT:
|
||||
builder->add(builder, part, va_arg(args, void*));
|
||||
continue;
|
||||
default:
|
||||
DBG1("builder part %N not supported by factory",
|
||||
builder_part_names, part);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return builder->build(builder);
|
||||
}
|
||||
|
||||
/** shredder all data on failure */
|
||||
va_start(args, subtype);
|
||||
while (TRUE)
|
||||
{
|
||||
part = va_arg(args, builder_part_t);
|
||||
|
||||
switch (part)
|
||||
{
|
||||
case BUILD_END:
|
||||
break;
|
||||
case BUILD_BLOB_ASN1_DER:
|
||||
{
|
||||
chunk_t chunk = va_arg(args, chunk_t);
|
||||
free(chunk.ptr);
|
||||
continue;
|
||||
}
|
||||
case BUILD_SIGNING_KEY:
|
||||
{
|
||||
private_key_t *private = va_arg(args, private_key_t*);
|
||||
private->destroy(private);
|
||||
continue;
|
||||
}
|
||||
case BUILD_PUBLIC_KEY:
|
||||
{
|
||||
public_key_t *public = va_arg(args, public_key_t*);
|
||||
public->destroy(public);
|
||||
continue;
|
||||
}
|
||||
case BUILD_SUBJECT:
|
||||
case BUILD_SUBJECT_ALTNAME:
|
||||
case BUILD_ISSUER:
|
||||
case BUILD_ISSUER_ALTNAME:
|
||||
{
|
||||
identification_t *id = va_arg(args, identification_t*);
|
||||
id->destroy(id);
|
||||
continue;
|
||||
}
|
||||
case BUILD_SIGNING_CERT:
|
||||
case BUILD_CA_CERT:
|
||||
case BUILD_CERT:
|
||||
{
|
||||
certificate_t *cert = va_arg(args, certificate_t*);
|
||||
cert->destroy(cert);
|
||||
continue;
|
||||
}
|
||||
case BUILD_KEY_SIZE:
|
||||
continue;
|
||||
default:
|
||||
DBG1("builder part %N not supported by factory",
|
||||
builder_part_names, part);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_factory_t.destroy
|
||||
*/
|
||||
static void destroy(private_credential_factory_t *this)
|
||||
{
|
||||
this->constructors->destroy_function(this->constructors, free);
|
||||
this->mutex->destroy(this->mutex);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
credential_factory_t *credential_factory_create()
|
||||
{
|
||||
private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
|
||||
|
||||
this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
|
||||
this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder;
|
||||
this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
|
||||
this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
|
||||
this->public.destroy = (void(*)(credential_factory_t*))destroy;
|
||||
|
||||
this->constructors = linked_list_create();
|
||||
|
||||
this->mutex = mutex_create(MUTEX_RECURSIVE);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup credential_factory credential_factory
|
||||
* @{ @ingroup credentials
|
||||
*/
|
||||
|
||||
#ifndef CREDENTIAL_FACTORY_H_
|
||||
#define CREDENTIAL_FACTORY_H_
|
||||
|
||||
typedef struct credential_factory_t credential_factory_t;
|
||||
typedef enum credential_type_t credential_type_t;
|
||||
|
||||
#include <credentials/keys/private_key.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
#include <credentials/certificates/certificate.h>
|
||||
#include <credentials/builder.h>
|
||||
|
||||
/**
|
||||
* Kind of credential.
|
||||
*/
|
||||
enum credential_type_t {
|
||||
/** private key, implemented in private_key_t */
|
||||
CRED_PRIVATE_KEY,
|
||||
/** public key, implemented in public_key_t */
|
||||
CRED_PUBLIC_KEY,
|
||||
/** certificates, implemented in certificate_t */
|
||||
CRED_CERTIFICATE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages credential construction functions and creates instances.
|
||||
*/
|
||||
struct credential_factory_t {
|
||||
|
||||
/**
|
||||
* Create a credential using a list of builder_part_t's.
|
||||
*
|
||||
* The variable argument list takes builder_part_t types followed
|
||||
* by the type specific value. The list must be terminated using BUILD_END.
|
||||
*
|
||||
* @param type credential type to build
|
||||
* @param subtype subtype specific for type of the credential
|
||||
* @param ... build_part_t arguments, BUILD_END terminated.
|
||||
* @return type specific credential, NULL if failed
|
||||
*/
|
||||
void* (*create)(credential_factory_t *this, credential_type_t type,
|
||||
int subtype, ...);
|
||||
|
||||
/**
|
||||
* Create a builder instance to build credentials.
|
||||
*
|
||||
* @param type type of credentials the builder creates
|
||||
* @param subtype type specific subtype, such as certificate_type_t
|
||||
* @return builder instance
|
||||
*/
|
||||
builder_t* (*create_builder)(credential_factory_t *this,
|
||||
credential_type_t type, int subtype);
|
||||
/**
|
||||
* Register a builder_t constructor function.
|
||||
*
|
||||
* @param type type of credential the builder creates
|
||||
* @param constructor builder constructor function to register
|
||||
*/
|
||||
void (*add_builder)(credential_factory_t *this,
|
||||
credential_type_t type, int subtype,
|
||||
builder_constructor_t constructor);
|
||||
/**
|
||||
* Unregister a builder_t constructor function.
|
||||
*
|
||||
* @param constructor constructor function to unregister.
|
||||
*/
|
||||
void (*remove_builder)(credential_factory_t *this,
|
||||
builder_constructor_t constructor);
|
||||
|
||||
/**
|
||||
* Destroy a credential_factory instance.
|
||||
*/
|
||||
void (*destroy)(credential_factory_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a credential_factory instance.
|
||||
*/
|
||||
credential_factory_t *credential_factory_create();
|
||||
|
||||
#endif /* CREDENTIAL_FACTORY_H_ @}*/
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "private_key.h"
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup private_key private_key
|
||||
* @{ @ingroup keys
|
||||
*/
|
||||
|
||||
#ifndef PRIVATE_KEY_H_
|
||||
#define PRIVATE_KEY_H_
|
||||
|
||||
typedef struct private_key_t private_key_t;
|
||||
|
||||
#include <utils/identification.h>
|
||||
#include <credentials/keys/public_key.h>
|
||||
|
||||
/**
|
||||
* Abstract private key interface.
|
||||
*/
|
||||
struct private_key_t {
|
||||
|
||||
/**
|
||||
* Get the key type.
|
||||
*
|
||||
* @return type of the key
|
||||
*/
|
||||
key_type_t (*get_type)(private_key_t *this);
|
||||
|
||||
/**
|
||||
* Create a signature over a chunk of data.
|
||||
*
|
||||
* @param scheme signature scheme to use
|
||||
* @param data chunk of data to sign
|
||||
* @param signature where to allocate created signature
|
||||
* @return TRUE if signature created
|
||||
*/
|
||||
bool (*sign)(private_key_t *this, signature_scheme_t scheme,
|
||||
chunk_t data, chunk_t *signature);
|
||||
/**
|
||||
* Decrypt a chunk of data.
|
||||
*
|
||||
* @param crypto chunk containing encrypted data
|
||||
* @param plain where to allocate decrypted data
|
||||
* @return TRUE if data decrypted and plaintext allocated
|
||||
*/
|
||||
bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain);
|
||||
|
||||
/**
|
||||
* Get the strength of the key in bytes.
|
||||
*
|
||||
* @return strength of the key in bytes
|
||||
*/
|
||||
size_t (*get_keysize) (private_key_t *this);
|
||||
|
||||
/**
|
||||
* Get a unique key identifier, such as a hash over the public key.
|
||||
*
|
||||
* @param type type of the key ID to get
|
||||
* @return unique ID of the key as identification_t, or NULL
|
||||
*/
|
||||
identification_t* (*get_id) (private_key_t *this, id_type_t type);
|
||||
|
||||
/**
|
||||
* Get the public part from the private key.
|
||||
*
|
||||
* @return public key
|
||||
*/
|
||||
public_key_t* (*get_public_key)(private_key_t *this);
|
||||
|
||||
/**
|
||||
* Check if a private key belongs to a public key.
|
||||
*
|
||||
* @param public public key
|
||||
* @return TRUE, if keys belong together
|
||||
*/
|
||||
bool (*belongs_to) (private_key_t *this, public_key_t *public);
|
||||
|
||||
/**
|
||||
* Get an encoded form of the private key.
|
||||
*
|
||||
* @todo Do we need a encoding type specification?
|
||||
*
|
||||
* @return allocated chunk containing encoded private key
|
||||
*/
|
||||
chunk_t (*get_encoding)(private_key_t *this);
|
||||
|
||||
/**
|
||||
* Increase the refcount to this private key.
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
private_key_t* (*get_ref)(private_key_t *this);
|
||||
|
||||
/**
|
||||
* Decrease refcount, destroy private_key if no more references.
|
||||
*/
|
||||
void (*destroy)(private_key_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a private key from a file.
|
||||
*
|
||||
* @param type type of the key
|
||||
* @param filename filename to read key from
|
||||
* @param passphrase passphrase to decrypt an encrypted key
|
||||
* @return loaded private key, NULL if failed
|
||||
*/
|
||||
private_key_t *private_key_create_from_file(key_type_t type, char *filename,
|
||||
chunk_t passphrase);
|
||||
|
||||
/**
|
||||
* Create a private key from a chunk.
|
||||
*
|
||||
* @param type type of the key
|
||||
* @param chunk chunk to create key from
|
||||
* @return loaded private key, NULL if failed
|
||||
*/
|
||||
private_key_t *private_key_create_from_chunk(key_type_t type, chunk_t chunk);
|
||||
|
||||
/**
|
||||
* Generate a new private key.
|
||||
*
|
||||
* @param type type of the key
|
||||
* @param size key size in bytes
|
||||
* @return generated private key, NULL if failed
|
||||
*/
|
||||
private_key_t *private_key_create_generated(key_type_t type, size_t size);
|
||||
|
||||
#endif /* PRIVATE_KEY_H_ @} */
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "public_key.h"
|
||||
|
||||
ENUM(key_type_names, KEY_RSA, KEY_RSA,
|
||||
"RSA"
|
||||
);
|
||||
|
||||
ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_RSA_EMSA_PKCS1_SHA512,
|
||||
"DEFAULT",
|
||||
"RSA_EMSA_PKCS1_MD5",
|
||||
"RSA_EMSA_PKCS1_SHA1",
|
||||
"RSA_EMSA_PKCS1_SHA256",
|
||||
"RSA_EMSA_PKCS1_SHA384",
|
||||
"RSA_EMSA_PKCS1_SHA512",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup public_key public_key
|
||||
* @{ @ingroup keys
|
||||
*/
|
||||
|
||||
#ifndef PUBLIC_KEY_H_
|
||||
#define PUBLIC_KEY_H_
|
||||
|
||||
typedef struct public_key_t public_key_t;
|
||||
typedef enum key_type_t key_type_t;
|
||||
typedef enum key_id_type_t key_id_type_t;
|
||||
typedef enum signature_scheme_t signature_scheme_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
/**
|
||||
* Type of a key pair, the used crypto system
|
||||
*/
|
||||
enum key_type_t {
|
||||
/** key type wildcard */
|
||||
KEY_ANY,
|
||||
/** RSA crypto system as in PKCS#1 */
|
||||
KEY_RSA,
|
||||
/** DSS, ElGamal, ECDSA, ... */
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names for key_type_t
|
||||
*/
|
||||
extern enum_name_t *key_type_names;
|
||||
|
||||
/**
|
||||
* Signature scheme for signature creation
|
||||
*
|
||||
* EMSA-PKCS1 signatures are from the PKCS#1 standard. They include
|
||||
* the ASN1-OID of the used hash algorithm.
|
||||
*/
|
||||
enum signature_scheme_t {
|
||||
/** default scheme of that underlying crypto system */
|
||||
SIGN_DEFAULT,
|
||||
/** EMSA-PKCS1 with MD5 */
|
||||
SIGN_RSA_EMSA_PKCS1_MD5,
|
||||
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash. */
|
||||
SIGN_RSA_EMSA_PKCS1_SHA1,
|
||||
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */
|
||||
SIGN_RSA_EMSA_PKCS1_SHA256,
|
||||
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */
|
||||
SIGN_RSA_EMSA_PKCS1_SHA384,
|
||||
/** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */
|
||||
SIGN_RSA_EMSA_PKCS1_SHA512,
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names for signature_scheme_t
|
||||
*/
|
||||
extern enum_name_t *signature_scheme_names;
|
||||
|
||||
/**
|
||||
* Abstract interface of a public key.
|
||||
*/
|
||||
struct public_key_t {
|
||||
|
||||
/**
|
||||
* Get the key type.
|
||||
*
|
||||
* @return type of the key
|
||||
*/
|
||||
key_type_t (*get_type)(public_key_t *this);
|
||||
|
||||
/**
|
||||
* Verifies a signature against a chunk of data.
|
||||
*
|
||||
* @param scheme signature scheme to use for verification, may be default
|
||||
* @param data data to check signature against
|
||||
* @param signature signature to check
|
||||
* @return TRUE if signature matches
|
||||
*/
|
||||
bool (*verify)(public_key_t *this, signature_scheme_t scheme,
|
||||
chunk_t data, chunk_t signature);
|
||||
|
||||
/**
|
||||
* Encrypt a chunk of data.
|
||||
*
|
||||
* @param crypto chunk containing plaintext data
|
||||
* @param plain where to allocate encrypted data
|
||||
* @return TRUE if data successfully encrypted
|
||||
*/
|
||||
bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain);
|
||||
|
||||
/**
|
||||
* Get the strength of the key in bytes.
|
||||
*
|
||||
* @return strength of the key in bytes
|
||||
*/
|
||||
size_t (*get_keysize) (public_key_t *this);
|
||||
|
||||
/**
|
||||
* Get a unique key identifier, such as a hash over the key.
|
||||
*
|
||||
* @param type type of the key ID to get
|
||||
* @return unique ID of the key as identification_t, or NULL
|
||||
*/
|
||||
identification_t* (*get_id) (public_key_t *this, id_type_t type);
|
||||
|
||||
/**
|
||||
* Get an encoded form of the key.
|
||||
*
|
||||
* @todo Do we need a encoding type specification?
|
||||
*
|
||||
* @return allocated chunk containing encoded key
|
||||
*/
|
||||
chunk_t (*get_encoding)(public_key_t *this);
|
||||
|
||||
/**
|
||||
* Increase the refcount of the key.
|
||||
*
|
||||
* @return this with an increased refcount
|
||||
*/
|
||||
public_key_t* (*get_ref)(public_key_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a public_key instance.
|
||||
*/
|
||||
void (*destroy)(public_key_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Read a public key from a file.
|
||||
*
|
||||
* @param type type of the key
|
||||
* @param filename filename to read key from
|
||||
* @return loaded public key, NULL if failed
|
||||
*/
|
||||
public_key_t *public_key_create_from_file(key_type_t type, char *filename);
|
||||
|
||||
/**
|
||||
* Create a public key from a chunk.
|
||||
*
|
||||
* @param type type of the key
|
||||
* @param chunk chunk to create key from
|
||||
* @return loaded public key, NULL if failed
|
||||
*/
|
||||
public_key_t *public_key_create_from_chunk(key_type_t type, chunk_t chunk);
|
||||
|
||||
#endif /* PUBLIC_KEY_H_ @} */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "shared_key.h"
|
||||
|
||||
ENUM(shared_key_type_names, SHARED_ANY, SHARED_PIN,
|
||||
"ANY",
|
||||
"IKE",
|
||||
"EAP",
|
||||
"PRIVATE_KEY_PASS",
|
||||
"PIN",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup shared_key shared_key
|
||||
* @{ @ingroup keys
|
||||
*/
|
||||
|
||||
#ifndef SHARED_KEY_H_
|
||||
#define SHARED_KEY_H_
|
||||
|
||||
#include <utils/enumerator.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
typedef struct shared_key_t shared_key_t;
|
||||
typedef enum shared_key_type_t shared_key_type_t;
|
||||
|
||||
/**
|
||||
* Type of a shared key.
|
||||
*/
|
||||
enum shared_key_type_t {
|
||||
/** wildcard for all keys */
|
||||
SHARED_ANY,
|
||||
/** PSK for IKE authentication */
|
||||
SHARED_IKE,
|
||||
/** key for a EAP authentication method */
|
||||
SHARED_EAP,
|
||||
/** key to decrypt encrypted private keys */
|
||||
SHARED_PRIVATE_KEY_PASS,
|
||||
/** PIN to unlock a smartcard */
|
||||
SHARED_PIN,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum names for shared_key_type_t
|
||||
*/
|
||||
extern enum_name_t *shared_key_type_names;
|
||||
|
||||
/**
|
||||
* A symmetric key shared between multiple owners.
|
||||
*
|
||||
* This class is not thread save, do not add owners while others might be
|
||||
* reading.
|
||||
*/
|
||||
struct shared_key_t {
|
||||
|
||||
/**
|
||||
* Get the kind of this key.
|
||||
*
|
||||
* @return type of the key
|
||||
*/
|
||||
shared_key_type_t (*get_type)(shared_key_t *this);
|
||||
|
||||
/**
|
||||
* Get the shared key data.
|
||||
*
|
||||
* @return chunk pointing to the internal key
|
||||
*/
|
||||
chunk_t (*get_key)(shared_key_t *this);
|
||||
|
||||
/**
|
||||
* Increase refcount of the key.
|
||||
*
|
||||
* @return this with an increased refcount
|
||||
*/
|
||||
shared_key_t* (*get_ref)(shared_key_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a shared_key instance if all references are gone.
|
||||
*/
|
||||
void (*destroy)(shared_key_t *this);
|
||||
};
|
||||
|
||||
#endif /** SHARED_KEY_H_ @} */
|
||||
@@ -1,636 +0,0 @@
|
||||
/**
|
||||
* @file ac.c
|
||||
*
|
||||
* @brief Implementation of x509ac_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
|
||||
* Copyright (C) 2003 Martin Berner, Lukas Suter
|
||||
* Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/pem.h>
|
||||
#include <crypto/x509.h>
|
||||
#include <crypto/ietf_attr_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/lexparser.h>
|
||||
|
||||
#include "ac.h"
|
||||
|
||||
#define ACERT_WARNING_INTERVAL 1 /* day */
|
||||
|
||||
typedef struct private_x509ac_t private_x509ac_t;
|
||||
|
||||
/**
|
||||
* Private data of a x509ac_t object.
|
||||
*/
|
||||
struct private_x509ac_t {
|
||||
/**
|
||||
* Public interface for this attribute certificate.
|
||||
*/
|
||||
x509ac_t public;
|
||||
|
||||
/**
|
||||
* Time when attribute certificate was installed
|
||||
*/
|
||||
time_t installed;
|
||||
|
||||
/**
|
||||
* X.509 attribute certificate in DER format
|
||||
*/
|
||||
chunk_t certificate;
|
||||
|
||||
/**
|
||||
* X.509 attribute certificate body over which signature is computed
|
||||
*/
|
||||
chunk_t certificateInfo;
|
||||
|
||||
/**
|
||||
* Version of the X.509 attribute certificate
|
||||
*/
|
||||
u_int version;
|
||||
|
||||
/**
|
||||
* Serial number of the X.509 attribute certificate
|
||||
*/
|
||||
chunk_t serialNumber;
|
||||
|
||||
/**
|
||||
* ID representing the issuer of the holder certificate
|
||||
*/
|
||||
identification_t *holderIssuer;
|
||||
|
||||
/**
|
||||
* Serial number of the holder certificate
|
||||
*/
|
||||
chunk_t holderSerial;
|
||||
|
||||
/**
|
||||
* ID representing the holder
|
||||
*/
|
||||
identification_t *entityName;
|
||||
|
||||
/**
|
||||
* ID representing the attribute certificate issuer
|
||||
*/
|
||||
identification_t *issuerName;
|
||||
|
||||
/**
|
||||
* Signature algorithm
|
||||
*/
|
||||
int sigAlg;
|
||||
|
||||
/**
|
||||
* Start time of certificate validity
|
||||
*/
|
||||
time_t notBefore;
|
||||
|
||||
/**
|
||||
* End time of certificate validity
|
||||
*/
|
||||
time_t notAfter;
|
||||
|
||||
/**
|
||||
* List of charging attributes
|
||||
*/
|
||||
linked_list_t *charging;
|
||||
|
||||
/**
|
||||
* List of groub attributes
|
||||
*/
|
||||
linked_list_t *groups;
|
||||
|
||||
/**
|
||||
* Authority Key Identifier
|
||||
*/
|
||||
chunk_t authKeyID;
|
||||
|
||||
/**
|
||||
* Authority Key Serial Number
|
||||
*/
|
||||
chunk_t authKeySerialNumber;
|
||||
|
||||
/**
|
||||
* No revocation information available
|
||||
*/
|
||||
bool noRevAvail;
|
||||
|
||||
/**
|
||||
* Signature algorithm (must be identical to sigAlg)
|
||||
*/
|
||||
int algorithm;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
*/
|
||||
chunk_t signature;
|
||||
};
|
||||
|
||||
/**
|
||||
* ASN.1 definition of roleSyntax
|
||||
*/
|
||||
static const asn1Object_t roleSyntaxObjects[] =
|
||||
{
|
||||
{ 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
|
||||
{ 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
|
||||
ASN1_OBJ }, /* 1 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
|
||||
{ 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
|
||||
};
|
||||
|
||||
#define ROLE_ROOF 4
|
||||
|
||||
/**
|
||||
* ASN.1 definition of an X509 attribute certificate
|
||||
*/
|
||||
static const asn1Object_t acObjects[] =
|
||||
{
|
||||
{ 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||||
{ 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
|
||||
{ 2, "version", ASN1_INTEGER, ASN1_DEF |
|
||||
ASN1_BODY }, /* 2 */
|
||||
{ 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
|
||||
{ 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
|
||||
{ 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
|
||||
{ 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
|
||||
{ 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
|
||||
ASN1_BODY }, /* 7 */
|
||||
{ 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
|
||||
{ 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
|
||||
ASN1_OBJ }, /* 10 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
|
||||
{ 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
|
||||
{ 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
|
||||
{ 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
|
||||
ASN1_BODY }, /* 14 */
|
||||
{ 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
|
||||
{ 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
|
||||
{ 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
|
||||
{ 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
|
||||
ASN1_OBJ }, /* 19 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
|
||||
{ 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
|
||||
{ 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
|
||||
{ 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
|
||||
{ 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
|
||||
{ 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
|
||||
ASN1_BODY }, /* 25 */
|
||||
{ 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
|
||||
{ 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
|
||||
{ 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
|
||||
{ 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
|
||||
{ 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
|
||||
ASN1_BODY }, /* 31 */
|
||||
{ 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
|
||||
{ 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
|
||||
{ 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
|
||||
{ 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
|
||||
{ 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
|
||||
{ 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
|
||||
{ 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
|
||||
{ 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
|
||||
{ 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
|
||||
{ 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
|
||||
{ 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
|
||||
{ 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
|
||||
{ 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
|
||||
{ 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
|
||||
{ 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
|
||||
{ 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
|
||||
{ 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
|
||||
{ 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
|
||||
{ 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
|
||||
ASN1_BODY }, /* 50 */
|
||||
{ 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
|
||||
{ 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
|
||||
{ 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
|
||||
{ 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
|
||||
};
|
||||
|
||||
#define AC_OBJ_CERTIFICATE 0
|
||||
#define AC_OBJ_CERTIFICATE_INFO 1
|
||||
#define AC_OBJ_VERSION 2
|
||||
#define AC_OBJ_HOLDER_ISSUER 5
|
||||
#define AC_OBJ_HOLDER_SERIAL 6
|
||||
#define AC_OBJ_ENTITY_NAME 10
|
||||
#define AC_OBJ_ISSUER_NAME 19
|
||||
#define AC_OBJ_ISSUER 23
|
||||
#define AC_OBJ_SIG_ALG 35
|
||||
#define AC_OBJ_SERIAL_NUMBER 36
|
||||
#define AC_OBJ_NOT_BEFORE 38
|
||||
#define AC_OBJ_NOT_AFTER 39
|
||||
#define AC_OBJ_ATTRIBUTE_TYPE 42
|
||||
#define AC_OBJ_ATTRIBUTE_VALUE 44
|
||||
#define AC_OBJ_EXTN_ID 49
|
||||
#define AC_OBJ_CRITICAL 50
|
||||
#define AC_OBJ_EXTN_VALUE 51
|
||||
#define AC_OBJ_ALGORITHM 53
|
||||
#define AC_OBJ_SIGNATURE 54
|
||||
#define AC_OBJ_ROOF 55
|
||||
|
||||
/**
|
||||
* Implements x509ac_t.is_valid
|
||||
*/
|
||||
static err_t is_valid(const private_x509ac_t *this, time_t *until)
|
||||
{
|
||||
time_t current_time = time(NULL);
|
||||
|
||||
DBG2(" not before : %T", &this->notBefore);
|
||||
DBG2(" current time: %T", ¤t_time);
|
||||
DBG2(" not after : %T", &this->notAfter);
|
||||
|
||||
if (until != NULL &&
|
||||
(*until == UNDEFINED_TIME || this->notAfter < *until))
|
||||
{
|
||||
*until = this->notAfter;
|
||||
}
|
||||
if (current_time < this->notBefore)
|
||||
{
|
||||
return "is not valid yet";
|
||||
}
|
||||
if (current_time > this->notAfter)
|
||||
{
|
||||
return "has expired";
|
||||
}
|
||||
DBG2(" attribute certificate is valid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509ac_t.is_newer
|
||||
*/
|
||||
static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other)
|
||||
{
|
||||
return this->notBefore > other->notBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509ac_t.equals_holder.
|
||||
*/
|
||||
static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other)
|
||||
{
|
||||
return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer)
|
||||
&& chunk_equals(this->holderSerial, other->holderSerial);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a directoryName
|
||||
*/
|
||||
static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
|
||||
{
|
||||
bool has_directoryName;
|
||||
linked_list_t *list = linked_list_create();
|
||||
|
||||
x509_parse_generalNames(blob, level, implicit, list);
|
||||
has_directoryName = list->get_count(list) > 0;
|
||||
|
||||
if (has_directoryName)
|
||||
{
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
identification_t *directoryName;
|
||||
bool first = TRUE;
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&directoryName))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
*name = directoryName;
|
||||
first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("more than one directory name - first selected");
|
||||
directoryName->destroy(directoryName);
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("no directoryName found");
|
||||
}
|
||||
|
||||
list->destroy(list);
|
||||
return has_directoryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses roleSyntax
|
||||
*/
|
||||
static void parse_roleSyntax(chunk_t blob, int level0)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
|
||||
asn1_init(&ctx, blob, level0, FALSE, FALSE);
|
||||
while (objectID < ROLE_ROOF)
|
||||
{
|
||||
if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an X.509 attribute certificate
|
||||
*/
|
||||
static bool parse_certificate(chunk_t blob, private_x509ac_t *this)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
bool critical;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
int type = OID_UNKNOWN;
|
||||
int extn_oid = OID_UNKNOWN;
|
||||
|
||||
asn1_init(&ctx, blob, 0, FALSE, FALSE);
|
||||
while (objectID < AC_OBJ_ROOF)
|
||||
{
|
||||
if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* those objects which will parsed further need the next higher level */
|
||||
level++;
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case AC_OBJ_CERTIFICATE:
|
||||
this->certificate = object;
|
||||
break;
|
||||
case AC_OBJ_CERTIFICATE_INFO:
|
||||
this->certificateInfo = object;
|
||||
break;
|
||||
case AC_OBJ_VERSION:
|
||||
this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
|
||||
DBG2(" v%d", this->version);
|
||||
if (this->version != 2)
|
||||
{
|
||||
DBG1("v%d attribute certificates are not supported", this->version);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_HOLDER_ISSUER:
|
||||
if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_HOLDER_SERIAL:
|
||||
this->holderSerial = object;
|
||||
break;
|
||||
case AC_OBJ_ENTITY_NAME:
|
||||
if (!parse_directoryName(object, level, TRUE, &this->entityName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_ISSUER_NAME:
|
||||
if (!parse_directoryName(object, level, FALSE, &this->issuerName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_SIG_ALG:
|
||||
this->sigAlg = parse_algorithmIdentifier(object, level, NULL);
|
||||
break;
|
||||
case AC_OBJ_SERIAL_NUMBER:
|
||||
this->serialNumber = object;
|
||||
break;
|
||||
case AC_OBJ_NOT_BEFORE:
|
||||
this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
|
||||
break;
|
||||
case AC_OBJ_NOT_AFTER:
|
||||
this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
|
||||
break;
|
||||
case AC_OBJ_ATTRIBUTE_TYPE:
|
||||
type = known_oid(object);
|
||||
break;
|
||||
case AC_OBJ_ATTRIBUTE_VALUE:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OID_AUTHENTICATION_INFO:
|
||||
DBG2(" need to parse authenticationInfo");
|
||||
break;
|
||||
case OID_ACCESS_IDENTITY:
|
||||
DBG2(" need to parse accessIdentity");
|
||||
break;
|
||||
case OID_CHARGING_IDENTITY:
|
||||
ietfAttr_list_create_from_chunk(object, this->charging, level);
|
||||
break;
|
||||
case OID_GROUP:
|
||||
ietfAttr_list_create_from_chunk(object, this->groups, level);
|
||||
break;
|
||||
case OID_ROLE:
|
||||
parse_roleSyntax(object, level);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_EXTN_ID:
|
||||
extn_oid = known_oid(object);
|
||||
break;
|
||||
case AC_OBJ_CRITICAL:
|
||||
critical = object.len && *object.ptr;
|
||||
DBG2(" %s",(critical)?"TRUE":"FALSE");
|
||||
break;
|
||||
case AC_OBJ_EXTN_VALUE:
|
||||
{
|
||||
switch (extn_oid)
|
||||
{
|
||||
case OID_CRL_DISTRIBUTION_POINTS:
|
||||
DBG2(" need to parse crlDistributionPoints");
|
||||
break;
|
||||
case OID_AUTHORITY_KEY_ID:
|
||||
x509_parse_authorityKeyIdentifier(object, level,
|
||||
&this->authKeyID, &this->authKeySerialNumber);
|
||||
break;
|
||||
case OID_TARGET_INFORMATION:
|
||||
DBG2(" need to parse targetInformation");
|
||||
break;
|
||||
case OID_NO_REV_AVAIL:
|
||||
this->noRevAvail = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AC_OBJ_ALGORITHM:
|
||||
this->algorithm = parse_algorithmIdentifier(object, level, NULL);
|
||||
break;
|
||||
case AC_OBJ_SIGNATURE:
|
||||
this->signature = object;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
this->installed = time(NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of x509ac_t.list.
|
||||
*/
|
||||
static void list(const private_x509ac_t *this, FILE *out, bool utc)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
fprintf(out, "%#T\n", &this->installed, utc);
|
||||
|
||||
if (this->entityName)
|
||||
{
|
||||
fprintf(out, " holder: '%D'\n", this->entityName);
|
||||
}
|
||||
if (this->holderIssuer)
|
||||
{
|
||||
fprintf(out, " hissuer: '%D'\n", this->holderIssuer);
|
||||
}
|
||||
if (this->holderSerial.ptr)
|
||||
{
|
||||
fprintf(out, " hserial: %#B\n", &this->holderSerial);
|
||||
}
|
||||
|
||||
/* list all group attributes on a single line */
|
||||
fprintf(out, " groups: ");
|
||||
ietfAttr_list_list(this->groups, out);
|
||||
fprintf(out, "\n");
|
||||
|
||||
fprintf(out, " issuer: '%D'\n", this->issuerName);
|
||||
fprintf(out, " serial: %#B\n", &this->serialNumber);
|
||||
|
||||
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
|
||||
if (now < this->notBefore)
|
||||
{
|
||||
fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "ok\n");
|
||||
}
|
||||
|
||||
fprintf(out, " not after %#T, ", &this->notAfter, utc);
|
||||
if (now > this->notAfter)
|
||||
{
|
||||
fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "ok");
|
||||
if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
|
||||
{
|
||||
fprintf(out, " (expires in %#V)", &now, &this->notAfter);
|
||||
}
|
||||
fprintf(out, " \n");
|
||||
}
|
||||
|
||||
if (this->authKeyID.ptr)
|
||||
{
|
||||
fprintf(out, " authkey: %#B\n", &this->authKeyID);
|
||||
}
|
||||
if (this->authKeySerialNumber.ptr)
|
||||
{
|
||||
fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements x509ac_t.destroy
|
||||
*/
|
||||
static void destroy(private_x509ac_t *this)
|
||||
{
|
||||
DESTROY_IF(this->holderIssuer);
|
||||
DESTROY_IF(this->entityName);
|
||||
DESTROY_IF(this->issuerName);
|
||||
ietfAttr_list_destroy(this->charging);
|
||||
ietfAttr_list_destroy(this->groups);
|
||||
free(this->certificate.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
x509ac_t *x509ac_create_from_chunk(chunk_t chunk)
|
||||
{
|
||||
private_x509ac_t *this = malloc_thing(private_x509ac_t);
|
||||
|
||||
/* initialize */
|
||||
this->holderIssuer = NULL;
|
||||
this->entityName = NULL;
|
||||
this->issuerName = NULL;
|
||||
this->charging = linked_list_create();
|
||||
this->groups = linked_list_create();
|
||||
|
||||
/* public functions */
|
||||
this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid;
|
||||
this->public.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer;
|
||||
this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder;
|
||||
this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list;
|
||||
this->public.destroy = (void (*) (x509ac_t*))destroy;
|
||||
|
||||
if (!parse_certificate(chunk, this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
x509ac_t *x509ac_create_from_file(const char *filename)
|
||||
{
|
||||
bool pgp = FALSE;
|
||||
chunk_t chunk = chunk_empty;
|
||||
|
||||
if (!pem_asn1_load_file(filename, NULL, "attribute certificate", &chunk, &pgp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return x509ac_create_from_chunk(chunk);
|
||||
}
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
* @file ac.h
|
||||
*
|
||||
* @brief Interface of x509ac_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
|
||||
* Copyright (C) 2003 Martin Berner, Lukas Suter
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#ifndef AC_H_
|
||||
#define AC_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct x509ac_t x509ac_t;
|
||||
|
||||
/**
|
||||
* @brief X.509 attribute certificate.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - x509ac_create_from_chunk()
|
||||
* - x509ac_create_from_file()
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
struct x509ac_t {
|
||||
|
||||
/**
|
||||
* @brief Checks the validity interval of the attribute certificate
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @param until until = min(until, notAfter)
|
||||
* @return NULL if the certificate is valid
|
||||
*/
|
||||
err_t (*is_valid) (const x509ac_t *this, time_t *until);
|
||||
|
||||
/** @brief Checks if this attr cert is newer than the other attr cert
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other other attr cert object
|
||||
* @return TRUE if this was issued more recently than other
|
||||
*/
|
||||
bool (*is_newer) (const x509ac_t *this, const x509ac_t *other);
|
||||
|
||||
/**
|
||||
* @brief Checks if two attribute certificates belong to the same holder
|
||||
*
|
||||
* @param this calling attribute certificate
|
||||
* @param that other attribute certificate
|
||||
* @return TRUE if same holder
|
||||
*/
|
||||
bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other);
|
||||
|
||||
/**
|
||||
* @brief Log the attribute certificate info to out.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param out stream to write to
|
||||
* @param utc TRUE for UTC times, FALSE for local time
|
||||
*/
|
||||
void (*list)(const x509ac_t *this, FILE *out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief Destroys the attribute certificate.
|
||||
*
|
||||
* @param this certificate to destroy
|
||||
*/
|
||||
void (*destroy) (x509ac_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read a x509 attribute certificate from a DER encoded blob.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @return created x509ac_t certificate, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
x509ac_t *x509ac_create_from_chunk(chunk_t chunk);
|
||||
|
||||
/**
|
||||
* @brief Read a x509 attribute certificate from a DER encoded file.
|
||||
*
|
||||
* @param filename file containing DER encoded data
|
||||
* @return created x509ac_t certificate, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
x509ac_t *x509ac_create_from_file(const char *filename);
|
||||
|
||||
#endif /* AC_H_ */
|
||||
|
||||
@@ -1,813 +0,0 @@
|
||||
/**
|
||||
* @file ca.c
|
||||
*
|
||||
* @brief Implementation of ca_info_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "x509.h"
|
||||
#include "crl.h"
|
||||
#include "ca.h"
|
||||
#include "ac.h"
|
||||
#include "certinfo.h"
|
||||
#include "ocsp.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/fetcher.h>
|
||||
|
||||
typedef struct private_ca_info_t private_ca_info_t;
|
||||
|
||||
/**
|
||||
* Private data of a ca_info_t object.
|
||||
*/
|
||||
struct private_ca_info_t {
|
||||
/**
|
||||
* Public interface for this ca info record
|
||||
*/
|
||||
ca_info_t public;
|
||||
|
||||
/**
|
||||
* Name of the ca info record
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* Time when ca info record was installed
|
||||
*/
|
||||
time_t installed;
|
||||
|
||||
/**
|
||||
* Distinguished Name of the CA
|
||||
*/
|
||||
x509_t *cacert;
|
||||
|
||||
/**
|
||||
* List of attribute certificates
|
||||
*/
|
||||
linked_list_t *attrcerts;
|
||||
|
||||
/**
|
||||
* List of crl URIs
|
||||
*/
|
||||
linked_list_t *crluris;
|
||||
|
||||
/**
|
||||
* List of ocsp URIs
|
||||
*/
|
||||
linked_list_t *ocspuris;
|
||||
|
||||
/**
|
||||
* CRL issued by this ca
|
||||
*/
|
||||
crl_t *crl;
|
||||
|
||||
/**
|
||||
* List of certificate info records
|
||||
*/
|
||||
linked_list_t *certinfos;
|
||||
|
||||
/**
|
||||
* mutex controls access to the elements:
|
||||
* name, crluris, ocspuris, crl, and certinfos
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* static options set by ca_info_set_options()
|
||||
*/
|
||||
static strict_t strict_crl_policy = STRICT_NO;
|
||||
static bool cache_crls = FALSE;
|
||||
static u_int crl_check_interval = 0;
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.equals
|
||||
*/
|
||||
static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
|
||||
{
|
||||
return chunk_equals(this->cacert->get_keyid(this->cacert),
|
||||
that->cacert->get_keyid(that->cacert));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.equals_name_release_info
|
||||
*/
|
||||
static bool equals_name_release_info(private_ca_info_t *this, const char *name)
|
||||
{
|
||||
bool found;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
found = this->name != NULL && streq(this->name, name);
|
||||
|
||||
if (found)
|
||||
{
|
||||
this->crluris->destroy_offset(this->crluris,
|
||||
offsetof(identification_t, destroy));
|
||||
this->crluris = linked_list_create();
|
||||
|
||||
this->ocspuris->destroy_offset(this->ocspuris,
|
||||
offsetof(identification_t, destroy));
|
||||
this->ocspuris = linked_list_create();
|
||||
|
||||
free(this->name);
|
||||
this->name = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.is_crl_issuer
|
||||
*/
|
||||
static bool is_cert_issuer(private_ca_info_t *this, const x509_t *cert)
|
||||
{
|
||||
return cert->is_issuer(cert, this->cacert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.is_crl_issuer
|
||||
*/
|
||||
static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
|
||||
{
|
||||
return crl->is_issuer(crl, this->cacert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.is_ca
|
||||
*/
|
||||
static bool is_ca(private_ca_info_t *this)
|
||||
{
|
||||
return this->cacert->is_ca(this->cacert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.is_strict
|
||||
*/
|
||||
static bool is_strict(private_ca_info_t *this)
|
||||
{
|
||||
bool strict = strict_crl_policy != STRICT_NO;
|
||||
|
||||
if (strict_crl_policy == STRICT_IFURI)
|
||||
{
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
strict = this->crluris->get_count(this->crluris) > 0 ||
|
||||
this->ocspuris->get_count(this->ocspuris) > 0;
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
return strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.has_crl
|
||||
*/
|
||||
static bool has_crl(private_ca_info_t *this)
|
||||
{
|
||||
bool found;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
found = this->crl != NULL;
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.has_certinfos
|
||||
*/
|
||||
static bool has_certinfos(private_ca_info_t *this)
|
||||
{
|
||||
bool found;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
found = this->certinfos->get_count(this->certinfos) > 0;
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.add_crl
|
||||
*/
|
||||
static void add_crl(private_ca_info_t *this, crl_t *crl)
|
||||
{
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
if (this->crl)
|
||||
{
|
||||
if (crl->is_newer(crl, this->crl))
|
||||
{
|
||||
this->crl->destroy(this->crl);
|
||||
this->crl = crl;
|
||||
DBG1(" this crl is newer - existing crl replaced");
|
||||
}
|
||||
else
|
||||
{
|
||||
crl->destroy(crl);
|
||||
DBG1(" this crl is not newer - existing crl retained");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->crl = crl;
|
||||
DBG2(" crl added");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.list_crl
|
||||
*/
|
||||
static void list_crl(private_ca_info_t *this, FILE *out, bool utc)
|
||||
{
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
this->crl->list(this->crl, out, utc);
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.list_certinfos
|
||||
*/
|
||||
static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
certinfo_t *certinfo;
|
||||
chunk_t authkey;
|
||||
|
||||
pthread_mutex_lock(&this->mutex);
|
||||
|
||||
authkey = this->cacert->get_subjectKeyID(this->cacert);
|
||||
fprintf(out," authname: '%D'\n", this->cacert->get_subject(this->cacert));
|
||||
fprintf(out," authkey: %#B\n", &authkey);
|
||||
|
||||
iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&certinfo))
|
||||
{
|
||||
time_t nextUpdate, thisUpdate, now;
|
||||
chunk_t serial;
|
||||
|
||||
now = time(NULL);
|
||||
nextUpdate = certinfo->get_nextUpdate(certinfo);
|
||||
thisUpdate = certinfo->get_thisUpdate(certinfo);
|
||||
serial = certinfo->get_serialNumber(certinfo);
|
||||
|
||||
fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
|
||||
if (now > nextUpdate)
|
||||
{
|
||||
fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
|
||||
}
|
||||
fprintf(out, " serial: %#B, %N\n", &serial,
|
||||
cert_status_names, certinfo->get_status(certinfo));
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an exact copy of an identification in a linked list
|
||||
*/
|
||||
static identification_t* find_identification(linked_list_t *list, identification_t *id)
|
||||
{
|
||||
identification_t *found_id = NULL, *current_id;
|
||||
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
|
||||
while (iterator->iterate(iterator, (void**)¤t_id))
|
||||
{
|
||||
if (id->equals(id, current_id))
|
||||
{
|
||||
found_id = current_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return found_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a unique identification to a linked list
|
||||
*/
|
||||
static identification_t *add_identification(linked_list_t *list, identification_t *id)
|
||||
{
|
||||
identification_t *found_id = find_identification(list, id);
|
||||
|
||||
if (found_id)
|
||||
{
|
||||
id->destroy(id);
|
||||
return found_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
list->insert_last(list, (void*)id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.add_crluri
|
||||
*/
|
||||
static void add_crluri(private_ca_info_t *this, chunk_t uri)
|
||||
{
|
||||
if (uri.len < 6 ||
|
||||
(strncasecmp(uri.ptr, "http", 4) != 0 &&
|
||||
strncasecmp(uri.ptr, "ldap", 4) != 0 &&
|
||||
strncasecmp(uri.ptr, "file", 4) != 0 &&
|
||||
strncasecmp(uri.ptr, "ftp", 3) != 0))
|
||||
{
|
||||
DBG1(" invalid crl uri '%.*s'", uri.len, uri.ptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
add_identification(this->crluris, crluri);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.add_ocspuri
|
||||
*/
|
||||
static void add_ocspuri(private_ca_info_t *this, chunk_t uri)
|
||||
{
|
||||
if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0)
|
||||
{
|
||||
DBG1(" invalid ocsp uri '%.*s'", uri.len, uri.ptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
identification_t *ocspuri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
add_identification(this->ocspuris, ocspuri);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.add_info.
|
||||
*/
|
||||
void add_info (private_ca_info_t *this, const private_ca_info_t *that)
|
||||
{
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
if (this->name == NULL && that->name != NULL)
|
||||
{
|
||||
this->name = strdup(that->name);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
|
||||
{
|
||||
identification_t *uri;
|
||||
|
||||
iterator_t *iterator = that->crluris->create_iterator(that->crluris, TRUE);
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
|
||||
{
|
||||
add_crluri(this, uri->get_encoding(uri));
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
{
|
||||
identification_t *uri;
|
||||
|
||||
iterator_t *iterator = that->ocspuris->create_iterator(that->ocspuris, TRUE);
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
|
||||
{
|
||||
add_ocspuri(this, uri->get_encoding(uri));
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.get_certificate.
|
||||
*/
|
||||
static x509_t* get_certificate(private_ca_info_t* this)
|
||||
{
|
||||
return this->cacert;
|
||||
}
|
||||
|
||||
/**
|
||||
* caches a crl by saving it to a given crl directory
|
||||
*/
|
||||
void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl)
|
||||
{
|
||||
char buffer[BUF_LEN];
|
||||
char *path;
|
||||
char *pos = buffer;
|
||||
int len = BUF_LEN;
|
||||
int n;
|
||||
|
||||
chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
|
||||
chunk_t uri;
|
||||
|
||||
uri.ptr = buffer;
|
||||
uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4;
|
||||
|
||||
if (uri.len >= BUF_LEN)
|
||||
{
|
||||
DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* print the file uri prefix */
|
||||
n = snprintf(pos, len, "file://");
|
||||
pos += n; len -= n;
|
||||
|
||||
/* remember the start of the path string */
|
||||
path = pos;
|
||||
|
||||
/* print the default crl directory path */
|
||||
n = snprintf(pos, len, "%s/", crl_dir);
|
||||
pos += n; len -= n;
|
||||
|
||||
/* create and print a unique crl filename derived from the authKeyID */
|
||||
while (authKeyID.len-- > 0)
|
||||
{
|
||||
n = snprintf(pos, len, "%02x", *authKeyID.ptr++);
|
||||
pos += n; len -= n;
|
||||
}
|
||||
|
||||
/* add the file suffix */
|
||||
n = snprintf(pos, len, ".crl");
|
||||
|
||||
if (crl->write_to_file(crl, path, 0022, TRUE))
|
||||
{
|
||||
identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
|
||||
|
||||
add_identification(this->crluris, crluri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.verify_by_crl.
|
||||
*/
|
||||
static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo,
|
||||
const char *crl_dir)
|
||||
{
|
||||
rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
|
||||
bool stale;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
if (this->crl == NULL)
|
||||
{
|
||||
stale = TRUE;
|
||||
DBG1("no crl is locally available");
|
||||
}
|
||||
else
|
||||
{
|
||||
stale = !this->crl->is_valid(this->crl);
|
||||
DBG1("crl is %s", stale? "stale":"valid");
|
||||
}
|
||||
|
||||
if (stale && crl_check_interval > 0)
|
||||
{
|
||||
iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
|
||||
identification_t *uri;
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
fetcher_t *fetcher;
|
||||
char uri_string[BUF_LEN];
|
||||
chunk_t uri_chunk = uri->get_encoding(uri);
|
||||
chunk_t response_chunk;
|
||||
|
||||
snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
|
||||
fetcher = fetcher_create(uri_string);
|
||||
|
||||
response_chunk = fetcher->get(fetcher);
|
||||
fetcher->destroy(fetcher);
|
||||
if (response_chunk.ptr != NULL)
|
||||
{
|
||||
crl_t *crl = crl_create_from_chunk(response_chunk);
|
||||
|
||||
if (crl == NULL)
|
||||
{
|
||||
free(response_chunk.ptr);
|
||||
continue;
|
||||
}
|
||||
if (!is_crl_issuer(this, crl))
|
||||
{
|
||||
DBG1(" fetched crl has wrong issuer");
|
||||
crl->destroy(crl);
|
||||
continue;
|
||||
}
|
||||
if (!crl->verify(crl, issuer_public_key))
|
||||
{
|
||||
DBG1("fetched crl signature is invalid");
|
||||
crl->destroy(crl);
|
||||
continue;
|
||||
}
|
||||
DBG2("fetched crl signature is valid");
|
||||
|
||||
if (this->crl == NULL)
|
||||
{
|
||||
this->crl = crl;
|
||||
}
|
||||
else if (crl->is_newer(crl, this->crl))
|
||||
{
|
||||
this->crl->destroy(this->crl);
|
||||
this->crl = crl;
|
||||
DBG1("this crl is newer - existing crl replaced");
|
||||
}
|
||||
else
|
||||
{
|
||||
crl->destroy(crl);
|
||||
DBG1("this crl is not newer - existing crl retained");
|
||||
continue;
|
||||
}
|
||||
if (crl->is_valid(crl))
|
||||
{
|
||||
if (cache_crls && strncasecmp(uri_string, "file", 4) != 0)
|
||||
{
|
||||
cache_crl(this, crl_dir, crl);
|
||||
}
|
||||
/* we found a valid crl and therefore exit the fetch loop */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("fetched crl is stale");
|
||||
}
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
if (this->crl)
|
||||
{
|
||||
if (!this->crl->verify(this->crl, issuer_public_key))
|
||||
{
|
||||
DBG1("crl signature is invalid");
|
||||
goto ret;
|
||||
}
|
||||
DBG2("crl signature is valid");
|
||||
|
||||
this->crl->get_status(this->crl, certinfo);
|
||||
}
|
||||
|
||||
ret:
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return certinfo->get_status(certinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.verify_by_ocsp.
|
||||
*/
|
||||
static cert_status_t verify_by_ocsp(private_ca_info_t* this,
|
||||
certinfo_t *certinfo,
|
||||
credential_store_t *credentials)
|
||||
{
|
||||
bool stale;
|
||||
iterator_t *iterator;
|
||||
certinfo_t *cached_certinfo = NULL;
|
||||
int comparison = 1;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
/* do we support OCSP at all? */
|
||||
if (this->ocspuris->get_count(this->ocspuris) == 0)
|
||||
{
|
||||
goto ret;
|
||||
}
|
||||
|
||||
iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
|
||||
|
||||
/* find the list insertion point in alphabetical order */
|
||||
while(iterator->iterate(iterator, (void**)&cached_certinfo))
|
||||
{
|
||||
comparison = certinfo->compare_serialNumber(certinfo, cached_certinfo);
|
||||
|
||||
if (comparison <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* do we have a valid certinfo_t for this serial number in our cache? */
|
||||
if (comparison == 0)
|
||||
{
|
||||
stale = cached_certinfo->get_nextUpdate(cached_certinfo) < time(NULL);
|
||||
DBG1("ocsp status in cache is %s", stale ? "stale":"fresh");
|
||||
}
|
||||
else
|
||||
{
|
||||
stale = TRUE;
|
||||
DBG1("ocsp status is not in cache");
|
||||
}
|
||||
|
||||
if (stale)
|
||||
{
|
||||
ocsp_t *ocsp;
|
||||
|
||||
ocsp = ocsp_create(this->cacert, this->ocspuris);
|
||||
ocsp->fetch(ocsp, certinfo, credentials);
|
||||
if (certinfo->get_status(certinfo) != CERT_UNDEFINED)
|
||||
{
|
||||
if (comparison != 0)
|
||||
{
|
||||
cached_certinfo = certinfo_create(certinfo->get_serialNumber(certinfo));
|
||||
|
||||
if (comparison > 0)
|
||||
{
|
||||
this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->insert_before(iterator, (void *)cached_certinfo);
|
||||
}
|
||||
}
|
||||
cached_certinfo->update(cached_certinfo, certinfo);
|
||||
}
|
||||
ocsp->destroy(ocsp);
|
||||
}
|
||||
else
|
||||
{
|
||||
certinfo->update(certinfo, cached_certinfo);
|
||||
}
|
||||
|
||||
iterator->destroy(iterator);
|
||||
|
||||
ret:
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return certinfo->get_status(certinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.purge_ocsp
|
||||
*/
|
||||
static void purge_ocsp(private_ca_info_t *this)
|
||||
{
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
this->certinfos->destroy_offset(this->certinfos,
|
||||
offsetof(certinfo_t, destroy));
|
||||
this->certinfos = linked_list_create();
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ca_info_t.destroy
|
||||
*/
|
||||
static void destroy(private_ca_info_t *this)
|
||||
{
|
||||
this->attrcerts->destroy_offset(this->attrcerts,
|
||||
offsetof(x509ac_t, destroy));
|
||||
this->crluris->destroy_offset(this->crluris,
|
||||
offsetof(identification_t, destroy));
|
||||
this->ocspuris->destroy_offset(this->ocspuris,
|
||||
offsetof(identification_t, destroy));
|
||||
this->certinfos->destroy_offset(this->certinfos,
|
||||
offsetof(certinfo_t, destroy));
|
||||
DESTROY_IF(this->crl);
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* list the info of this CA
|
||||
*/
|
||||
static void list(private_ca_info_t* this, FILE* out, bool utc)
|
||||
{
|
||||
chunk_t chunk;
|
||||
identification_t *uri;
|
||||
iterator_t *iterator;
|
||||
bool first;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
fprintf(out, "%#T", &this->installed, utc);
|
||||
|
||||
if (this->name)
|
||||
{
|
||||
fprintf(out, ", \"%s\"\n", this->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
fprintf(out, " authname: '%D'\n", this->cacert->get_subject(this->cacert));
|
||||
chunk = this->cacert->get_subjectKeyID(this->cacert);
|
||||
fprintf(out, " authkey: %#B\n", &chunk);
|
||||
chunk = this->cacert->get_keyid(this->cacert);
|
||||
fprintf(out, " keyid: %#B\n", &chunk);
|
||||
|
||||
first = TRUE;
|
||||
iterator = this->crluris->create_iterator(this->crluris, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
fprintf(out, " %s '%D'\n", first ? "crluris:":" ", uri);
|
||||
first = FALSE;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
first = TRUE;
|
||||
iterator = this->ocspuris->create_iterator(this->ocspuris, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
fprintf(out, " %s '%D'\n", first ? "ocspuris:":" ", uri);
|
||||
first = FALSE;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ca_info_set_options(strict_t strict, bool cache, u_int interval)
|
||||
{
|
||||
strict_crl_policy = strict;
|
||||
cache_crls = cache;
|
||||
crl_check_interval = interval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ca_info_t *ca_info_create(const char *name, x509_t *cacert)
|
||||
{
|
||||
private_ca_info_t *this = malloc_thing(private_ca_info_t);
|
||||
|
||||
/* initialize */
|
||||
this->installed = time(NULL);
|
||||
this->name = (name == NULL)? NULL:strdup(name);
|
||||
this->cacert = cacert;
|
||||
this->attrcerts = linked_list_create();
|
||||
this->crluris = linked_list_create();
|
||||
this->ocspuris = linked_list_create();
|
||||
this->certinfos = linked_list_create();
|
||||
this->crl = NULL;
|
||||
|
||||
/* initialize the mutex */
|
||||
pthread_mutex_init(&(this->mutex), NULL);
|
||||
|
||||
/* public functions */
|
||||
this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals;
|
||||
this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info;
|
||||
this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer;
|
||||
this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer;
|
||||
this->public.is_ca = (bool (*) (ca_info_t*))is_ca;
|
||||
this->public.is_strict = (bool (*) (ca_info_t*))is_strict;
|
||||
this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info;
|
||||
this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl;
|
||||
this->public.has_crl = (bool (*) (ca_info_t*))has_crl;
|
||||
this->public.has_certinfos = (bool (*) (ca_info_t*))has_certinfos;
|
||||
this->public.list = (void (*) (ca_info_t*,FILE*,bool))list;
|
||||
this->public.list_crl = (void (*) (ca_info_t*,FILE*,bool))list_crl;
|
||||
this->public.list_certinfos = (void (*) (ca_info_t*,FILE*,bool))list_certinfos;
|
||||
this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
|
||||
this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
|
||||
this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
|
||||
this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl;
|
||||
this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
|
||||
this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
|
||||
this->public.destroy = (void (*) (ca_info_t*))destroy;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,243 +0,0 @@
|
||||
/**
|
||||
* @file ca.h
|
||||
*
|
||||
* @brief Interface of ca_info_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CA_H_
|
||||
#define CA_H_
|
||||
|
||||
typedef struct ca_info_t ca_info_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#include "x509.h"
|
||||
#include "crl.h"
|
||||
|
||||
#define MAX_CA_PATH_LEN 7
|
||||
|
||||
/*forward declaration */
|
||||
struct credential_store_t;
|
||||
|
||||
/**
|
||||
* @brief X.509 certification authority information record
|
||||
*
|
||||
* @b Constructors:
|
||||
* - ca_info_create()
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
struct ca_info_t {
|
||||
|
||||
/**
|
||||
* @brief Compare two ca info records
|
||||
*
|
||||
* Comparison is done via the keyid of the ca certificate
|
||||
*
|
||||
* @param this first ca info object
|
||||
* @param that second ca info objct
|
||||
* @return TRUE if a match is found
|
||||
*/
|
||||
bool (*equals) (const ca_info_t *this, const ca_info_t* that);
|
||||
|
||||
/**
|
||||
* @brief If the ca info record has the same name then release the name and URIs
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return TRUE if a match is found
|
||||
*/
|
||||
bool (*equals_name_release_info) (ca_info_t *this, const char *name);
|
||||
|
||||
/**
|
||||
* @brief Checks if a certificate was issued by this ca
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param cert certificate to be checked
|
||||
* @return TRUE if the issuing ca has been found
|
||||
*/
|
||||
bool (*is_cert_issuer) (ca_info_t *this, const x509_t *cert);
|
||||
|
||||
/**
|
||||
* @brief Checks if a crl was issued by this ca
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param crl crl to be checked
|
||||
* @return TRUE if the issuing ca has been found
|
||||
*/
|
||||
bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl);
|
||||
|
||||
/**
|
||||
* @brief Checks if the ca certificate has the isCA flag set
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return TRUE if the isCA flag is set
|
||||
*/
|
||||
bool (*is_ca) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Checks if the ca enforces a strict crl policy
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return TRUE if the crl policy is strict
|
||||
*/
|
||||
bool (*is_strict) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Merges info from a secondary ca info object
|
||||
*
|
||||
* @param this primary ca info object
|
||||
* @param that secondary ca info object
|
||||
*/
|
||||
void (*add_info) (ca_info_t *this, const ca_info_t *that);
|
||||
|
||||
/**
|
||||
* @brief Adds a new or replaces an obsoleted CRL
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param crl crl to be added
|
||||
*/
|
||||
void (*add_crl) (ca_info_t *this, crl_t *crl);
|
||||
|
||||
/**
|
||||
* @brief Does the CA have a CRL?
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return TRUE if crl is available
|
||||
*/
|
||||
bool (*has_crl) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Does the CA have OCSP certinfos?
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return TRUE if there are any certinfos
|
||||
*/
|
||||
bool (*has_certinfos) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Print the CA info onto the console
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param out output stream
|
||||
* @param utc TRUE - utc
|
||||
FALSE - local time
|
||||
*/
|
||||
void (*list) (ca_info_t *this, FILE *out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief List the CRL onto the console
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param out output stream
|
||||
* @param utc TRUE - utc
|
||||
FALSE - local time
|
||||
*/
|
||||
void (*list_crl) (ca_info_t *this, FILE *out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief List the OCSP certinfos onto the console
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param out output stream
|
||||
* @param utc TRUE - utc
|
||||
FALSE - local time
|
||||
*/
|
||||
void (*list_certinfos) (ca_info_t *this, FILE *out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief Adds a CRL URI to a list
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param uri crl uri to be added
|
||||
*/
|
||||
void (*add_crluri) (ca_info_t *this, chunk_t uri);
|
||||
|
||||
/**
|
||||
* @brief Adds a OCSP URI to a list
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param uri ocsp uri to be added
|
||||
*/
|
||||
void (*add_ocspuri) (ca_info_t *this, chunk_t uri);
|
||||
|
||||
/**
|
||||
* @brief Get the ca certificate
|
||||
*
|
||||
* @param this ca info object
|
||||
* @return ca certificate
|
||||
*/
|
||||
x509_t* (*get_certificate) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Verify the status of a certificate by CRL
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param certinfo detailed certificate status information
|
||||
* @param crl_dir directory where fetched crls should be stored
|
||||
* @return certificate status
|
||||
*/
|
||||
cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir);
|
||||
|
||||
/**
|
||||
* @brief Verify the status of a certificate by OCSP
|
||||
*
|
||||
* @param this ca info object
|
||||
* @param certinfo detailed certificate status information
|
||||
* @param credentials credential store needed for trust path verification
|
||||
* @return certificate status
|
||||
*/
|
||||
cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, struct credential_store_t* credentials);
|
||||
|
||||
/**
|
||||
* @brief Purge the OCSP certinfos of a ca info record
|
||||
*
|
||||
* @param this ca info object
|
||||
*/
|
||||
void (*purge_ocsp) (ca_info_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a ca info record
|
||||
*
|
||||
* @param this ca info to destroy
|
||||
*/
|
||||
void (*destroy) (ca_info_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set ca info options
|
||||
*
|
||||
* @param cache TRUE if crls shall be cached by storing them
|
||||
* @param interval crl_check_interval to be set in seconds
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void ca_info_set_options(strict_t strict, bool cache, u_int interval);
|
||||
|
||||
/**
|
||||
* @brief Create a ca info record
|
||||
*
|
||||
* @param name name of the ca info record
|
||||
* @param cacert path to the ca certificate
|
||||
* @return created ca_info_t, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
ca_info_t *ca_info_create(const char *name, x509_t *cacert);
|
||||
|
||||
#endif /* CA_H_ */
|
||||
@@ -1,257 +0,0 @@
|
||||
/**
|
||||
* @file certinfo.c
|
||||
*
|
||||
* @brief Implementation of certinfo_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#include "certinfo.h"
|
||||
|
||||
typedef struct private_certinfo_t private_certinfo_t;
|
||||
|
||||
/**
|
||||
* Private data of a certinfo_t object.
|
||||
*/
|
||||
struct private_certinfo_t {
|
||||
/**
|
||||
* Public interface for this certificate status information object.
|
||||
*/
|
||||
certinfo_t public;
|
||||
|
||||
/**
|
||||
* Serial number of the certificate
|
||||
*/
|
||||
chunk_t serialNumber;
|
||||
|
||||
/**
|
||||
* Certificate status
|
||||
*/
|
||||
cert_status_t status;
|
||||
|
||||
/**
|
||||
* Certificate status is for one-time use only
|
||||
*/
|
||||
bool once;
|
||||
|
||||
/**
|
||||
* Time when the certificate status info was generated
|
||||
*/
|
||||
time_t thisUpdate;
|
||||
|
||||
/**
|
||||
* Time when an updated certifcate status info will be available
|
||||
*/
|
||||
time_t nextUpdate;
|
||||
|
||||
/**
|
||||
* Time of certificate revocation
|
||||
*/
|
||||
time_t revocationTime;
|
||||
|
||||
/**
|
||||
* Reason of certificate revocation
|
||||
*/
|
||||
crl_reason_t revocationReason;
|
||||
};
|
||||
|
||||
ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
|
||||
"good",
|
||||
"revoked",
|
||||
"unknown",
|
||||
"unknown",
|
||||
"untrusted",
|
||||
);
|
||||
|
||||
ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
|
||||
"unspecified",
|
||||
"key compromise",
|
||||
"ca compromise",
|
||||
"affiliation changed",
|
||||
"superseded",
|
||||
"cessation of operation",
|
||||
"certificate hold",
|
||||
"reason #7",
|
||||
"remove from crl",
|
||||
);
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.compare_serialNumber
|
||||
*/
|
||||
static int compare_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
|
||||
{
|
||||
return chunk_compare(this->serialNumber, that->serialNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.equals_serialNumber
|
||||
*/
|
||||
static bool equals_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
|
||||
{
|
||||
return chunk_equals(this->serialNumber, that->serialNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_serialNumber
|
||||
*/
|
||||
static chunk_t get_serialNumber(const private_certinfo_t *this)
|
||||
{
|
||||
return this->serialNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_status
|
||||
*/
|
||||
static void set_status(private_certinfo_t *this, cert_status_t status)
|
||||
{
|
||||
this->status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_status
|
||||
*/
|
||||
static cert_status_t get_status(const private_certinfo_t *this)
|
||||
{
|
||||
return this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_thisUpdate
|
||||
*/
|
||||
static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate)
|
||||
{
|
||||
this->thisUpdate = thisUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_thisUpdate
|
||||
*/
|
||||
static time_t get_thisUpdate(const private_certinfo_t *this)
|
||||
{
|
||||
return this->thisUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_nextUpdate
|
||||
*/
|
||||
static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate)
|
||||
{
|
||||
this->nextUpdate = nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_nextUpdate
|
||||
*/
|
||||
static time_t get_nextUpdate(const private_certinfo_t *this)
|
||||
{
|
||||
return this->nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_revocationTime
|
||||
*/
|
||||
static void set_revocationTime(private_certinfo_t *this, time_t revocationTime)
|
||||
{
|
||||
this->revocationTime = revocationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_revocationTime
|
||||
*/
|
||||
static time_t get_revocationTime(const private_certinfo_t *this)
|
||||
{
|
||||
return this->revocationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.set_revocationReason
|
||||
*/
|
||||
static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
|
||||
{
|
||||
this->revocationReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.get_revocationReason
|
||||
*/
|
||||
static crl_reason_t get_revocationReason(const private_certinfo_t *this)
|
||||
{
|
||||
return this->revocationReason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.update
|
||||
*/
|
||||
static void update(private_certinfo_t *this, const private_certinfo_t *that)
|
||||
{
|
||||
if (equals_serialNumber(this, that))
|
||||
{
|
||||
chunk_t this_serialNumber = this->serialNumber;
|
||||
|
||||
*this = *that;
|
||||
this->serialNumber = this_serialNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements certinfo_t.destroy
|
||||
*/
|
||||
static void destroy(private_certinfo_t *this)
|
||||
{
|
||||
free(this->serialNumber.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
certinfo_t *certinfo_create(chunk_t serial)
|
||||
{
|
||||
private_certinfo_t *this = malloc_thing(private_certinfo_t);
|
||||
|
||||
/* initialize */
|
||||
this->serialNumber = chunk_clone(serial);
|
||||
this->status = CERT_UNDEFINED;
|
||||
this->thisUpdate = UNDEFINED_TIME;
|
||||
this->nextUpdate = UNDEFINED_TIME;
|
||||
this->revocationTime = UNDEFINED_TIME;
|
||||
this->revocationReason = REASON_UNSPECIFIED;
|
||||
|
||||
/* public functions */
|
||||
this->public.compare_serialNumber = (int (*) (const certinfo_t*,const certinfo_t*))compare_serialNumber;
|
||||
this->public.equals_serialNumber = (bool (*) (const certinfo_t*,const certinfo_t*))equals_serialNumber;
|
||||
this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
|
||||
this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
|
||||
this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
|
||||
this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate;
|
||||
this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate;
|
||||
this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
|
||||
this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
|
||||
this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
|
||||
this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
|
||||
this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
|
||||
this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
|
||||
this->public.update = (void (*) (certinfo_t*, const certinfo_t*))update;
|
||||
this->public.destroy = (void (*) (certinfo_t*))destroy;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/**
|
||||
* @file certinfo.h
|
||||
*
|
||||
* @brief Interface of certinfo_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CERTINFO_H_
|
||||
#define CERTINFO_H_
|
||||
|
||||
typedef enum cert_status_t cert_status_t;
|
||||
typedef enum crl_reason_t crl_reason_t;
|
||||
typedef struct certinfo_t certinfo_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* RFC 2560 OCSP - certificate status
|
||||
*/
|
||||
enum cert_status_t {
|
||||
CERT_GOOD = 0,
|
||||
CERT_REVOKED = 1,
|
||||
CERT_UNKNOWN = 2,
|
||||
CERT_UNDEFINED = 3,
|
||||
CERT_UNTRUSTED = 4 /* private use */
|
||||
};
|
||||
|
||||
extern enum_name_t *cert_status_names;
|
||||
|
||||
/**
|
||||
* RFC 2459 CRL reason codes
|
||||
*/
|
||||
enum crl_reason_t {
|
||||
REASON_UNSPECIFIED = 0,
|
||||
REASON_KEY_COMPROMISE = 1,
|
||||
REASON_CA_COMPROMISE = 2,
|
||||
REASON_AFFILIATION_CHANGED = 3,
|
||||
REASON_SUPERSEDED = 4,
|
||||
REASON_CESSATION_OF_OPERATON = 5,
|
||||
REASON_CERTIFICATE_HOLD = 6,
|
||||
REASON_REMOVE_FROM_CRL = 8
|
||||
};
|
||||
|
||||
extern enum_name_t *crl_reason_names;
|
||||
|
||||
/**
|
||||
* @brief X.509 certificate status information
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
struct certinfo_t {
|
||||
|
||||
/**
|
||||
* @brief Check if both certinfo objects have the same serialNumber.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param that second certinfo_t object
|
||||
* @return TRUE if the same serialNumber
|
||||
*/
|
||||
bool (*equals_serialNumber) (const certinfo_t *this, const certinfo_t *that);
|
||||
|
||||
/**
|
||||
* @brief Compares two serial numbers.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param that second certinfo_t object
|
||||
* @return negative if this is smaller than that
|
||||
* zero if this equals that
|
||||
* positive if this is greater than that
|
||||
*/
|
||||
int (*compare_serialNumber) (const certinfo_t *this, const certinfo_t *that);
|
||||
|
||||
/**
|
||||
* @brief Get serial number.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return serialNumber
|
||||
*/
|
||||
chunk_t (*get_serialNumber) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set certificate status.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param status status
|
||||
*/
|
||||
void (*set_status) (certinfo_t *this, cert_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Get certificate status.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return status
|
||||
*/
|
||||
cert_status_t (*get_status) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set thisUpdate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param thisUpdate thisUpdate
|
||||
*/
|
||||
void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate);
|
||||
|
||||
/**
|
||||
* @brief Get thisUpdate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return thisUpdate
|
||||
*/
|
||||
time_t (*get_thisUpdate) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set nextUpdate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param nextUpdate
|
||||
*/
|
||||
void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
|
||||
|
||||
/**
|
||||
* @brief Get nextUpdate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return nextUpdate
|
||||
*/
|
||||
time_t (*get_nextUpdate) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set revocationTime.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param revocationTime revocationTime
|
||||
*/
|
||||
void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
|
||||
|
||||
/**
|
||||
* @brief Get revocationTime.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return revocationTime
|
||||
*/
|
||||
time_t (*get_revocationTime) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set revocationReason.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param reason revocationReason
|
||||
*/
|
||||
void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
|
||||
|
||||
/**
|
||||
* @brief Get revocationReason.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return revocationReason
|
||||
*/
|
||||
crl_reason_t (*get_revocationReason) (const certinfo_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set revocationReason.
|
||||
*
|
||||
* @param this calling object to be updated
|
||||
* @param that object containing updated information
|
||||
*/
|
||||
void (*update) (certinfo_t *this, const certinfo_t *that);
|
||||
|
||||
/**
|
||||
* @brief Destroys the certinfo_t object.
|
||||
*
|
||||
* @param this certinfo_t to destroy
|
||||
*/
|
||||
void (*destroy) (certinfo_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a certinfo_t object.
|
||||
*
|
||||
* @param serial chunk serial number of the certificate
|
||||
* @return created certinfo_t object
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
certinfo_t *certinfo_create(chunk_t serial);
|
||||
|
||||
#endif /* CERTINFO_H_ */
|
||||
@@ -1,536 +0,0 @@
|
||||
/**
|
||||
* @file crl.c
|
||||
*
|
||||
* @brief Implementation of crl_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/pem.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
#include "certinfo.h"
|
||||
#include "x509.h"
|
||||
#include "crl.h"
|
||||
|
||||
#define CRL_WARNING_INTERVAL 7 /* days */
|
||||
|
||||
/* access structure for a revoked certificate */
|
||||
|
||||
typedef struct revokedCert_t revokedCert_t;
|
||||
|
||||
struct revokedCert_t {
|
||||
chunk_t userCertificate;
|
||||
time_t revocationDate;
|
||||
crl_reason_t revocationReason;
|
||||
};
|
||||
|
||||
typedef struct private_crl_t private_crl_t;
|
||||
|
||||
/**
|
||||
* Private data of a crl_t object.
|
||||
*/
|
||||
struct private_crl_t {
|
||||
/**
|
||||
* Public interface for this crl.
|
||||
*/
|
||||
crl_t public;
|
||||
|
||||
/**
|
||||
* Time when crl was installed
|
||||
*/
|
||||
time_t installed;
|
||||
|
||||
/**
|
||||
* List of crlDistributionPoints
|
||||
*/
|
||||
linked_list_t *crlDistributionPoints;
|
||||
|
||||
/**
|
||||
* X.509 crl in DER format
|
||||
*/
|
||||
chunk_t certificateList;
|
||||
|
||||
/**
|
||||
* X.509 crl body over which signature is computed
|
||||
*/
|
||||
chunk_t tbsCertList;
|
||||
|
||||
/**
|
||||
* Version of the X.509 crl
|
||||
*/
|
||||
u_int version;
|
||||
|
||||
/**
|
||||
* Signature algorithm
|
||||
*/
|
||||
int sigAlg;
|
||||
|
||||
/**
|
||||
* ID representing the crl issuer
|
||||
*/
|
||||
identification_t *issuer;
|
||||
|
||||
/**
|
||||
* CRL number
|
||||
*/
|
||||
chunk_t crlNumber;
|
||||
|
||||
/**
|
||||
* Time when the crl was generated
|
||||
*/
|
||||
time_t thisUpdate;
|
||||
|
||||
/**
|
||||
* Time when an update crl will be available
|
||||
*/
|
||||
time_t nextUpdate;
|
||||
|
||||
/**
|
||||
* List of identification_t's representing subjectAltNames
|
||||
*/
|
||||
linked_list_t *revokedCertificates;
|
||||
|
||||
/**
|
||||
* Authority Key Identifier
|
||||
*/
|
||||
chunk_t authKeyID;
|
||||
|
||||
/**
|
||||
* Authority Key Serial Number
|
||||
*/
|
||||
chunk_t authKeySerialNumber;
|
||||
|
||||
/**
|
||||
* Signature algorithm (must be identical to sigAlg)
|
||||
*/
|
||||
int algorithm;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
*/
|
||||
chunk_t signature;
|
||||
};
|
||||
|
||||
/**
|
||||
* ASN.1 definition of an X.509 certificate revocation list
|
||||
*/
|
||||
static const asn1Object_t crlObjects[] = {
|
||||
{ 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||||
{ 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
|
||||
{ 2, "version", ASN1_INTEGER, ASN1_OPT |
|
||||
ASN1_BODY }, /* 2 */
|
||||
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
|
||||
{ 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
|
||||
{ 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
|
||||
{ 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
|
||||
{ 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
|
||||
{ 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
|
||||
ASN1_LOOP }, /* 8 */
|
||||
{ 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
|
||||
{ 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
|
||||
{ 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
|
||||
{ 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
|
||||
ASN1_LOOP }, /* 12 */
|
||||
{ 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
|
||||
{ 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
|
||||
{ 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
|
||||
ASN1_BODY }, /* 15 */
|
||||
{ 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
|
||||
{ 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
|
||||
{ 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
|
||||
{ 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
|
||||
{ 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
|
||||
{ 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
|
||||
{ 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
|
||||
{ 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
|
||||
ASN1_BODY }, /* 23 */
|
||||
{ 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
|
||||
{ 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
|
||||
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
|
||||
{ 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
|
||||
{ 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
|
||||
};
|
||||
|
||||
#define CRL_OBJ_CERTIFICATE_LIST 0
|
||||
#define CRL_OBJ_TBS_CERT_LIST 1
|
||||
#define CRL_OBJ_VERSION 2
|
||||
#define CRL_OBJ_SIG_ALG 4
|
||||
#define CRL_OBJ_ISSUER 5
|
||||
#define CRL_OBJ_THIS_UPDATE 6
|
||||
#define CRL_OBJ_NEXT_UPDATE 7
|
||||
#define CRL_OBJ_USER_CERTIFICATE 10
|
||||
#define CRL_OBJ_REVOCATION_DATE 11
|
||||
#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
|
||||
#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
|
||||
#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
|
||||
#define CRL_OBJ_EXTN_ID 22
|
||||
#define CRL_OBJ_CRITICAL 23
|
||||
#define CRL_OBJ_EXTN_VALUE 24
|
||||
#define CRL_OBJ_ALGORITHM 27
|
||||
#define CRL_OBJ_SIGNATURE 28
|
||||
#define CRL_OBJ_ROOF 29
|
||||
|
||||
/**
|
||||
* Parses a CRL revocation reason code
|
||||
*/
|
||||
static crl_reason_t parse_crl_reasonCode(chunk_t object)
|
||||
{
|
||||
crl_reason_t reason = REASON_UNSPECIFIED;
|
||||
|
||||
if (*object.ptr == ASN1_ENUMERATED && asn1_length(&object) == 1)
|
||||
{
|
||||
reason = *object.ptr;
|
||||
}
|
||||
DBG2(" '%N'", crl_reason_names, reason);
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an X.509 Certificate Revocation List (CRL)
|
||||
*/
|
||||
bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
bool critical;
|
||||
chunk_t extnID;
|
||||
chunk_t userCertificate = chunk_empty;
|
||||
revokedCert_t *revokedCert = NULL;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
|
||||
asn1_init(&ctx, blob, level0, FALSE, FALSE);
|
||||
|
||||
while (objectID < CRL_OBJ_ROOF)
|
||||
{
|
||||
if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
|
||||
return FALSE;
|
||||
|
||||
/* those objects which will parsed further need the next higher level */
|
||||
level++;
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case CRL_OBJ_CERTIFICATE_LIST:
|
||||
crl->certificateList = object;
|
||||
break;
|
||||
case CRL_OBJ_TBS_CERT_LIST:
|
||||
crl->tbsCertList = object;
|
||||
break;
|
||||
case CRL_OBJ_VERSION:
|
||||
crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
|
||||
DBG2(" v%d", crl->version);
|
||||
break;
|
||||
case CRL_OBJ_SIG_ALG:
|
||||
crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
|
||||
break;
|
||||
case CRL_OBJ_ISSUER:
|
||||
crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
|
||||
DBG2(" '%D'", crl->issuer);
|
||||
break;
|
||||
case CRL_OBJ_THIS_UPDATE:
|
||||
crl->thisUpdate = parse_time(object, level);
|
||||
break;
|
||||
case CRL_OBJ_NEXT_UPDATE:
|
||||
crl->nextUpdate = parse_time(object, level);
|
||||
break;
|
||||
case CRL_OBJ_USER_CERTIFICATE:
|
||||
userCertificate = object;
|
||||
break;
|
||||
case CRL_OBJ_REVOCATION_DATE:
|
||||
revokedCert = malloc_thing(revokedCert_t);
|
||||
revokedCert->userCertificate = userCertificate;
|
||||
revokedCert->revocationDate = parse_time(object, level);
|
||||
revokedCert->revocationReason = REASON_UNSPECIFIED;
|
||||
crl->revokedCertificates->insert_last(crl->revokedCertificates, (void *)revokedCert);
|
||||
break;
|
||||
case CRL_OBJ_CRL_ENTRY_EXTN_ID:
|
||||
case CRL_OBJ_EXTN_ID:
|
||||
extnID = object;
|
||||
break;
|
||||
case CRL_OBJ_CRL_ENTRY_CRITICAL:
|
||||
case CRL_OBJ_CRITICAL:
|
||||
critical = object.len && *object.ptr;
|
||||
DBG2(" %s",(critical)?"TRUE":"FALSE");
|
||||
break;
|
||||
case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
|
||||
case CRL_OBJ_EXTN_VALUE:
|
||||
{
|
||||
int extn_oid = known_oid(extnID);
|
||||
|
||||
if (revokedCert && extn_oid == OID_CRL_REASON_CODE)
|
||||
{
|
||||
revokedCert->revocationReason = parse_crl_reasonCode(object);
|
||||
}
|
||||
else if (extn_oid == OID_AUTHORITY_KEY_ID)
|
||||
{
|
||||
x509_parse_authorityKeyIdentifier(object, level,
|
||||
&crl->authKeyID, &crl->authKeySerialNumber);
|
||||
}
|
||||
else if (extn_oid == OID_CRL_NUMBER)
|
||||
{
|
||||
if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
crl->crlNumber = object;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRL_OBJ_ALGORITHM:
|
||||
crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
|
||||
if (crl->algorithm != crl->sigAlg)
|
||||
{
|
||||
DBG1(" signature algorithms do not agree");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case CRL_OBJ_SIGNATURE:
|
||||
crl->signature = object;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
time(&crl->installed);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.is_valid
|
||||
*/
|
||||
static bool is_valid(const private_crl_t *this)
|
||||
{
|
||||
time_t current_time = time(NULL);
|
||||
|
||||
DBG2(" this update : %T", &this->thisUpdate);
|
||||
DBG2(" current time: %T", ¤t_time);
|
||||
DBG2(" next update: %T", &this->nextUpdate);
|
||||
|
||||
return current_time < this->nextUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.get_issuer
|
||||
*/
|
||||
static identification_t *get_issuer(const private_crl_t *this)
|
||||
{
|
||||
return this->issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.equals_issuer
|
||||
*/
|
||||
static bool equals_issuer(const private_crl_t *this, const private_crl_t *other)
|
||||
{
|
||||
return (this->authKeyID.ptr)
|
||||
? chunk_equals(this->authKeyID, other->authKeyID)
|
||||
: (this->issuer->equals(this->issuer, other->issuer)
|
||||
&& chunk_equals_or_null(this->authKeySerialNumber, other->authKeySerialNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.is_issuer
|
||||
*/
|
||||
static bool is_issuer(const private_crl_t *this, const x509_t *issuer)
|
||||
{
|
||||
return (this->authKeyID.ptr)
|
||||
? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer))
|
||||
: (this->issuer->equals(this->issuer, issuer->get_subject(issuer))
|
||||
&& chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.is_newer
|
||||
*/
|
||||
static bool is_newer(const private_crl_t *this, const private_crl_t *other)
|
||||
{
|
||||
return (this->nextUpdate > other->nextUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.verify
|
||||
*/
|
||||
static bool verify(const private_crl_t *this, const rsa_public_key_t *signer)
|
||||
{
|
||||
hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->algorithm);
|
||||
|
||||
if (algorithm == HASH_UNKNOWN)
|
||||
{
|
||||
DBG1(" unknown signature algorithm");
|
||||
return FALSE;
|
||||
}
|
||||
return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertList, this->signature) == SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.get_status
|
||||
*/
|
||||
static void get_status(const private_crl_t *this, certinfo_t *certinfo)
|
||||
{
|
||||
chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
|
||||
iterator_t *iterator;
|
||||
revokedCert_t *revokedCert;
|
||||
|
||||
certinfo->set_nextUpdate(certinfo, this->nextUpdate);
|
||||
certinfo->set_status(certinfo, CERT_GOOD);
|
||||
|
||||
iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&revokedCert))
|
||||
{
|
||||
if (chunk_equals(serialNumber, revokedCert->userCertificate))
|
||||
{
|
||||
certinfo->set_status(certinfo, CERT_REVOKED);
|
||||
certinfo->set_revocationTime(certinfo, revokedCert->revocationDate);
|
||||
certinfo->set_revocationReason(certinfo, revokedCert->revocationReason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.write_to_file.
|
||||
*/
|
||||
static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force)
|
||||
{
|
||||
return chunk_write(this->certificateList, path, "crl", mask, force);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements crl_t.destroy
|
||||
*/
|
||||
static void destroy(private_crl_t *this)
|
||||
{
|
||||
this->revokedCertificates->destroy_function(this->revokedCertificates, free);
|
||||
this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
|
||||
offsetof(identification_t, destroy));
|
||||
DESTROY_IF(this->issuer);
|
||||
free(this->certificateList.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crl_t.list.
|
||||
*/
|
||||
static void list(private_crl_t *this, FILE* out, bool utc)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
fprintf(out, "%#T, revoked certs: %d\n", &this->installed, utc,
|
||||
this->revokedCertificates->get_count(this->revokedCertificates));
|
||||
fprintf(out, " issuer: '%D'\n", this->issuer);
|
||||
if (this->crlNumber.ptr)
|
||||
{
|
||||
fprintf(out, " crlnumber: %#B\n", &this->crlNumber);
|
||||
}
|
||||
fprintf(out, " updates: this %#T\n", &this->thisUpdate, utc);
|
||||
fprintf(out, " next %#T ", &this->nextUpdate, utc);
|
||||
if (this->nextUpdate == UNDEFINED_TIME)
|
||||
{
|
||||
fprintf(out, "ok (expires never)\n");
|
||||
}
|
||||
else if (now > this->nextUpdate)
|
||||
{
|
||||
fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
|
||||
}
|
||||
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
|
||||
{
|
||||
fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "ok\n");
|
||||
}
|
||||
if (this->authKeyID.ptr)
|
||||
{
|
||||
fprintf(out, " authkey: %#B\n", &this->authKeyID);
|
||||
}
|
||||
if (this->authKeySerialNumber.ptr)
|
||||
{
|
||||
fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
crl_t *crl_create_from_chunk(chunk_t chunk)
|
||||
{
|
||||
private_crl_t *this = malloc_thing(private_crl_t);
|
||||
|
||||
/* initialize */
|
||||
this->crlDistributionPoints = linked_list_create();
|
||||
this->tbsCertList = chunk_empty;
|
||||
this->issuer = NULL;
|
||||
this->crlNumber = chunk_empty;
|
||||
this->revokedCertificates = linked_list_create();
|
||||
this->authKeyID = chunk_empty;
|
||||
this->authKeySerialNumber = chunk_empty;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
|
||||
this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
|
||||
this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
|
||||
this->public.is_valid = (bool (*) (const crl_t*))is_valid;
|
||||
this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
|
||||
this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
|
||||
this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
|
||||
this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file;
|
||||
this->public.list = (void(*)(crl_t*, FILE* out, bool utc))list;
|
||||
this->public.destroy = (void (*) (crl_t*))destroy;
|
||||
|
||||
if (!parse_x509crl(chunk, 0, this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
crl_t *crl_create_from_file(const char *filename)
|
||||
{
|
||||
bool pgp = FALSE;
|
||||
chunk_t chunk = chunk_empty;
|
||||
|
||||
if (!pem_asn1_load_file(filename, NULL, "crl", &chunk, &pgp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return crl_create_from_chunk(chunk);
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* @file crl.h
|
||||
*
|
||||
* @brief Interface of crl_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#ifndef CRL_H_
|
||||
#define CRL_H_
|
||||
|
||||
typedef struct crl_t crl_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <crypto/certinfo.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/iterator.h>
|
||||
|
||||
/**
|
||||
* @brief X.509 certificate revocation list
|
||||
*
|
||||
* @b Constructors:
|
||||
* - crl_create_from_chunk()
|
||||
* - crl_create_from_file()
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
struct crl_t {
|
||||
|
||||
/**
|
||||
* @brief Get the crl's issuer ID.
|
||||
*
|
||||
* The resulting ID is always a identification_t
|
||||
* of type ID_DER_ASN1_DN.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return issuers ID
|
||||
*/
|
||||
identification_t *(*get_issuer) (const crl_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if both crls have the same issuer.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other other crl
|
||||
* @return TRUE if the same issuer
|
||||
*/
|
||||
bool (*equals_issuer) (const crl_t *this, const crl_t *other);
|
||||
|
||||
/**
|
||||
* @brief Check if ia candidate cert is the issuer of the crl
|
||||
*
|
||||
* @param this calling object
|
||||
* @param issuer candidate issuer of the crl
|
||||
* @return TRUE if issuer
|
||||
*/
|
||||
bool (*is_issuer) (const crl_t *this, const x509_t *issuer);
|
||||
|
||||
/**
|
||||
* @brief Checks the validity interval of the crl
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if the crl is valid
|
||||
*/
|
||||
bool (*is_valid) (const crl_t *this);
|
||||
|
||||
/**
|
||||
* @brief Checks if this crl is newer (thisUpdate) than the other crl
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other other crl object
|
||||
* @return TRUE if this was issued more recently than other
|
||||
*/
|
||||
bool (*is_newer) (const crl_t *this, const crl_t *other);
|
||||
|
||||
/**
|
||||
* @brief Check if a crl is trustworthy.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param signer signer's RSA public key
|
||||
* @return TRUE if crl is trustworthy
|
||||
*/
|
||||
bool (*verify) (const crl_t *this, const rsa_public_key_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Get the certificate status
|
||||
*
|
||||
* @param this calling object
|
||||
* @param certinfo certinfo is updated
|
||||
*/
|
||||
void (*get_status) (const crl_t *this, certinfo_t *certinfo);
|
||||
|
||||
/**
|
||||
* @brief Log the info of this CRL to out.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param out stream to write to
|
||||
* @param utc TRUE for UTC, FALSE for local time
|
||||
*/
|
||||
void (*list)(crl_t *this, FILE* out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief Write a der-encoded crl to a file
|
||||
*
|
||||
* @param this calling object
|
||||
* @param path path where the file is to be stored
|
||||
* @param mask file access control rights
|
||||
* @param force overwrite the file if it already exists
|
||||
* @return TRUE if successfully written
|
||||
*/
|
||||
bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force);
|
||||
|
||||
/**
|
||||
* @brief Destroys the crl.
|
||||
*
|
||||
* @param this crl to destroy
|
||||
*/
|
||||
void (*destroy) (crl_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read a x509 crl from a DER encoded blob.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @return created crl_t, or NULL if invalid.
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
crl_t *crl_create_from_chunk(chunk_t chunk);
|
||||
|
||||
/**
|
||||
* @brief Read a x509 crl from a DER encoded file.
|
||||
*
|
||||
* @param filename file containing DER encoded data
|
||||
* @return created crl_t, or NULL if invalid.
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
crl_t *crl_create_from_file(const char *filename);
|
||||
|
||||
#endif /* CRL_H_ */
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file crypter.c
|
||||
*
|
||||
* @brief Generic constructor for crypter_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,15 +12,12 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include "crypter.h"
|
||||
|
||||
#include <crypto/crypters/aes_cbc_crypter.h>
|
||||
#include <crypto/crypters/des_crypter.h>
|
||||
|
||||
|
||||
ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
|
||||
"UNDEFINED");
|
||||
ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
|
||||
@@ -46,23 +36,3 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
|
||||
"AES_CTR");
|
||||
ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
|
||||
{
|
||||
switch (encryption_algorithm)
|
||||
{
|
||||
case ENCR_AES_CBC:
|
||||
{
|
||||
return (crypter_t*)aes_cbc_crypter_create(key_size);
|
||||
}
|
||||
case ENCR_DES:
|
||||
case ENCR_3DES:
|
||||
{
|
||||
return (crypter_t*)des_crypter_create(encryption_algorithm);
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file crypter.h
|
||||
*
|
||||
* @brief Interface crypter_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup crypter crypter
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef CRYPTER_H_
|
||||
@@ -30,21 +30,12 @@ typedef struct crypter_t crypter_t;
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief Encryption algorithm, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* Currently only the following algorithms are implemented:
|
||||
* - ENCR_AES_CBC
|
||||
* - ENCR_DES
|
||||
* - ENCR_3DES
|
||||
*
|
||||
* @ingroup crypters
|
||||
* Encryption algorithm, as in IKEv2 RFC 3.3.2.
|
||||
*/
|
||||
enum encryption_algorithm_t {
|
||||
ENCR_UNDEFINED = 1024,
|
||||
ENCR_DES_IV64 = 1,
|
||||
/** Implemented in class des_crypter_t */
|
||||
ENCR_DES = 2,
|
||||
/** Implemented in class des_crypter_t */
|
||||
ENCR_3DES = 3,
|
||||
ENCR_RC5 = 4,
|
||||
ENCR_IDEA = 5,
|
||||
@@ -53,7 +44,6 @@ enum encryption_algorithm_t {
|
||||
ENCR_3IDEA = 8,
|
||||
ENCR_DES_IV32 = 9,
|
||||
ENCR_NULL = 11,
|
||||
/** Implemented in class aes_cbc_crypter_t */
|
||||
ENCR_AES_CBC = 12,
|
||||
ENCR_AES_CTR = 13
|
||||
};
|
||||
@@ -64,92 +54,58 @@ enum encryption_algorithm_t {
|
||||
extern enum_name_t *encryption_algorithm_names;
|
||||
|
||||
/**
|
||||
* @brief Generic interface for symmetric encryption algorithms.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - crypter_create()
|
||||
*
|
||||
* @ingroup crypters
|
||||
* Generic interface for symmetric encryption algorithms.
|
||||
*/
|
||||
struct crypter_t {
|
||||
|
||||
/**
|
||||
* @brief Encrypt a chunk of data and allocate space for the encrypted value.
|
||||
* Encrypt a chunk of data and allocate space for the encrypted value.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to encrypt
|
||||
* @param iv initializing vector
|
||||
* @param[out] encrypted pointer where the encrypted bytes will be written
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - INVALID_ARG if data size not a multiple of block size
|
||||
* @param data data to encrypt
|
||||
* @param iv initializing vector
|
||||
* @param encrypted pointer where the encrypted bytes will be written
|
||||
* @return SUCCESS, or INVALID_ARG if size invalid
|
||||
*/
|
||||
status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
|
||||
status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
|
||||
chunk_t *encrypted);
|
||||
|
||||
/**
|
||||
* @brief Decrypt a chunk of data and allocate space for the decrypted value.
|
||||
* Decrypt a chunk of data and allocate space for the decrypted value.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to decrypt
|
||||
* @param iv initializing vector
|
||||
* @param[out] encrypted pointer where the decrypted bytes will be written
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - INVALID_ARG if data size not a multiple of block size
|
||||
* @param data data to decrypt
|
||||
* @param iv initializing vector
|
||||
* @param encrypted pointer where the decrypted bytes will be written
|
||||
* @return SUCCESS, or INVALID_ARG if invalid
|
||||
*/
|
||||
status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted);
|
||||
status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
|
||||
chunk_t *decrypted);
|
||||
|
||||
/**
|
||||
* @brief Get the block size of this crypter_t object.
|
||||
* Get the block size of the crypto algorithm.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return block size in bytes
|
||||
*/
|
||||
size_t (*get_block_size) (crypter_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the key size of this crypter_t object.
|
||||
* Get the key size of the crypto algorithm.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return key size in bytes
|
||||
*/
|
||||
size_t (*get_key_size) (crypter_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the key for this crypter_t object.
|
||||
* Set the key.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param key key to set
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - INVALID_ARG if key length invalid
|
||||
* @return SUCCESS, or INVALID_ARG if key length invalid
|
||||
*/
|
||||
status_t (*set_key) (crypter_t *this, chunk_t key);
|
||||
|
||||
/**
|
||||
* @brief Destroys a crypter_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
* Destroys a crypter_t object.
|
||||
*/
|
||||
void (*destroy) (crypter_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generic constructor for crypter_t objects.
|
||||
*
|
||||
* Currently only the following algorithms are implemented:
|
||||
* - ENCR_AES_CBC
|
||||
* - ENCR_DES
|
||||
* - ENCR_3DES
|
||||
*
|
||||
* The key_size is ignored for algorithms with fixed key size.
|
||||
*
|
||||
* @param encryption_algorithm Algorithm to use for crypter
|
||||
* @param key_size size of the key in bytes
|
||||
* @return
|
||||
* - crypter_t object
|
||||
* - NULL if encryption algorithm/key_size is not supported
|
||||
*/
|
||||
crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
|
||||
|
||||
#endif /*CRYPTER_H_*/
|
||||
#endif /*CRYPTER_H_ @} */
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "crypto_factory.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/mutex.h>
|
||||
|
||||
typedef struct crypter_entry_t crypter_entry_t;
|
||||
struct crypter_entry_t {
|
||||
/** encryption algorithm */
|
||||
encryption_algorithm_t algo;
|
||||
/** associated constructor */
|
||||
crypter_constructor_t create;
|
||||
};
|
||||
|
||||
typedef struct signer_entry_t signer_entry_t;
|
||||
struct signer_entry_t {
|
||||
/** integrity algorithm */
|
||||
integrity_algorithm_t algo;
|
||||
/** associated constructor */
|
||||
signer_constructor_t create;
|
||||
};
|
||||
|
||||
typedef struct hasher_entry_t hasher_entry_t;
|
||||
struct hasher_entry_t {
|
||||
/** hash algorithm */
|
||||
hash_algorithm_t algo;
|
||||
/** associated constructor */
|
||||
hasher_constructor_t create;
|
||||
};
|
||||
|
||||
typedef struct prf_entry_t prf_entry_t;
|
||||
struct prf_entry_t {
|
||||
/** hash algorithm */
|
||||
pseudo_random_function_t algo;
|
||||
/** associated constructor */
|
||||
prf_constructor_t create;
|
||||
};
|
||||
|
||||
typedef struct dh_entry_t dh_entry_t;
|
||||
struct dh_entry_t {
|
||||
/** hash algorithm */
|
||||
diffie_hellman_group_t group;
|
||||
/** associated constructor */
|
||||
dh_constructor_t create;
|
||||
};
|
||||
|
||||
typedef struct private_crypto_factory_t private_crypto_factory_t;
|
||||
|
||||
/**
|
||||
* private data of crypto_factory
|
||||
*/
|
||||
struct private_crypto_factory_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
crypto_factory_t public;
|
||||
|
||||
/**
|
||||
* registered crypters, as crypter_entry_t
|
||||
*/
|
||||
linked_list_t *crypters;
|
||||
|
||||
/**
|
||||
* registered signers, as signer_entry_t
|
||||
*/
|
||||
linked_list_t *signers;
|
||||
|
||||
/**
|
||||
* registered hashers, as hasher_entry_t
|
||||
*/
|
||||
linked_list_t *hashers;
|
||||
|
||||
/**
|
||||
* registered perfs, as prf_entry_t
|
||||
*/
|
||||
linked_list_t *prfs;
|
||||
|
||||
/**
|
||||
* registered diffie hellman, as dh_entry_t
|
||||
*/
|
||||
linked_list_t *dhs;
|
||||
|
||||
/**
|
||||
* mutex to lock access to modules
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.create_crypter.
|
||||
*/
|
||||
static crypter_t* create_crypter(private_crypto_factory_t *this,
|
||||
encryption_algorithm_t algo, size_t key_size)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
crypter_entry_t *entry;
|
||||
crypter_t *crypter = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->crypters->create_enumerator(this->crypters);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->algo == algo)
|
||||
{
|
||||
crypter = entry->create(algo, key_size);
|
||||
if (crypter)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return crypter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.create_signer.
|
||||
*/
|
||||
static signer_t* create_signer(private_crypto_factory_t *this,
|
||||
integrity_algorithm_t algo)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
signer_entry_t *entry;
|
||||
signer_t *signer = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->signers->create_enumerator(this->signers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->algo == algo)
|
||||
{
|
||||
signer = entry->create(algo);
|
||||
if (signer)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
return signer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.create_hasher.
|
||||
*/
|
||||
static hasher_t* create_hasher(private_crypto_factory_t *this,
|
||||
hash_algorithm_t algo)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
hasher_entry_t *entry;
|
||||
hasher_t *hasher = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->hashers->create_enumerator(this->hashers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (algo == HASH_PREFERRED || entry->algo == algo)
|
||||
{
|
||||
hasher = entry->create(entry->algo);
|
||||
if (hasher)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return hasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.create_prf.
|
||||
*/
|
||||
static prf_t* create_prf(private_crypto_factory_t *this,
|
||||
pseudo_random_function_t algo)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
prf_entry_t *entry;
|
||||
prf_t *prf = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->prfs->create_enumerator(this->prfs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->algo == algo)
|
||||
{
|
||||
prf = entry->create(algo);
|
||||
if (prf)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return prf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.create_dh.
|
||||
*/
|
||||
static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
|
||||
diffie_hellman_group_t group)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
dh_entry_t *entry;
|
||||
diffie_hellman_t *diffie_hellman = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->dhs->create_enumerator(this->dhs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->group == group)
|
||||
{
|
||||
diffie_hellman = entry->create(group);
|
||||
if (diffie_hellman)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return diffie_hellman;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.add_crypter.
|
||||
*/
|
||||
static void add_crypter(private_crypto_factory_t *this,
|
||||
encryption_algorithm_t algo,
|
||||
crypter_constructor_t create)
|
||||
{
|
||||
crypter_entry_t *entry = malloc_thing(crypter_entry_t);
|
||||
|
||||
entry->algo = algo;
|
||||
entry->create = create;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->crypters->insert_last(this->crypters, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.remove_crypter.
|
||||
*/
|
||||
static void remove_crypter(private_crypto_factory_t *this,
|
||||
crypter_constructor_t create)
|
||||
{
|
||||
crypter_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->crypters->create_enumerator(this->crypters);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->crypters->remove_at(this->crypters, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.add_signer.
|
||||
*/
|
||||
static void add_signer(private_crypto_factory_t *this,
|
||||
integrity_algorithm_t algo, signer_constructor_t create)
|
||||
{
|
||||
signer_entry_t *entry = malloc_thing(signer_entry_t);
|
||||
|
||||
entry->algo = algo;
|
||||
entry->create = create;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->signers->insert_last(this->signers, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.remove_signer.
|
||||
*/
|
||||
static void remove_signer(private_crypto_factory_t *this,
|
||||
signer_constructor_t create)
|
||||
{
|
||||
signer_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->signers->create_enumerator(this->signers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->signers->remove_at(this->signers, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.add_hasher.
|
||||
*/
|
||||
static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
|
||||
hasher_constructor_t create)
|
||||
{
|
||||
hasher_entry_t *entry = malloc_thing(hasher_entry_t);
|
||||
|
||||
entry->algo = algo;
|
||||
entry->create = create;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->hashers->insert_last(this->hashers, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.remove_hasher.
|
||||
*/
|
||||
static void remove_hasher(private_crypto_factory_t *this,
|
||||
hasher_constructor_t create)
|
||||
{
|
||||
hasher_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->hashers->create_enumerator(this->hashers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->hashers->remove_at(this->hashers, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.add_prf.
|
||||
*/
|
||||
static void add_prf(private_crypto_factory_t *this,
|
||||
pseudo_random_function_t algo, prf_constructor_t create)
|
||||
{
|
||||
prf_entry_t *entry = malloc_thing(prf_entry_t);
|
||||
|
||||
entry->algo = algo;
|
||||
entry->create = create;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->prfs->insert_last(this->prfs, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.remove_prf.
|
||||
*/
|
||||
static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
|
||||
{
|
||||
prf_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->prfs->create_enumerator(this->prfs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->prfs->remove_at(this->prfs, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.add_dh.
|
||||
*/
|
||||
static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group,
|
||||
dh_constructor_t create)
|
||||
{
|
||||
dh_entry_t *entry = malloc_thing(dh_entry_t);
|
||||
|
||||
entry->group = group;
|
||||
entry->create = create;
|
||||
this->mutex->lock(this->mutex);
|
||||
this->dhs->insert_last(this->dhs, entry);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.remove_dh.
|
||||
*/
|
||||
static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create)
|
||||
{
|
||||
dh_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->dhs->create_enumerator(this->dhs);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->dhs->remove_at(this->dhs, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypto_factory_t.destroy
|
||||
*/
|
||||
static void destroy(private_crypto_factory_t *this)
|
||||
{
|
||||
this->crypters->destroy_function(this->crypters, free);
|
||||
this->signers->destroy_function(this->signers, free);
|
||||
this->hashers->destroy_function(this->hashers, free);
|
||||
this->prfs->destroy_function(this->prfs, free);
|
||||
this->dhs->destroy_function(this->dhs, free);
|
||||
this->mutex->destroy(this->mutex);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
crypto_factory_t *crypto_factory_create()
|
||||
{
|
||||
private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t);
|
||||
|
||||
this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter;
|
||||
this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer;
|
||||
this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher;
|
||||
this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf;
|
||||
this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh;
|
||||
this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter;
|
||||
this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter;
|
||||
this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer;
|
||||
this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer;
|
||||
this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher;
|
||||
this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher;
|
||||
this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf;
|
||||
this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf;
|
||||
this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh;
|
||||
this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh;
|
||||
this->public.destroy = (void(*)(crypto_factory_t*))destroy;
|
||||
|
||||
this->crypters = linked_list_create();
|
||||
this->signers = linked_list_create();
|
||||
this->hashers = linked_list_create();
|
||||
this->prfs = linked_list_create();
|
||||
this->dhs = linked_list_create();
|
||||
this->mutex = mutex_create(MUTEX_RECURSIVE);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup crypto_factory crypto_factory
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_FACTORY_H_
|
||||
#define CRYPTO_FACTORY_H_
|
||||
|
||||
typedef struct crypto_factory_t crypto_factory_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/crypters/crypter.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
|
||||
/**
|
||||
* Constructor function for crypters
|
||||
*/
|
||||
typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
|
||||
size_t key_size);
|
||||
/**
|
||||
* Constructor function for signers
|
||||
*/
|
||||
typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for hashers
|
||||
*/
|
||||
typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for pseudo random fucntions
|
||||
*/
|
||||
typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
|
||||
|
||||
/**
|
||||
* Constructor function for diffie hellman
|
||||
*/
|
||||
typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group);
|
||||
|
||||
/**
|
||||
* Handles crypto modules and creates instances.
|
||||
*/
|
||||
struct crypto_factory_t {
|
||||
|
||||
/**
|
||||
* Create a crypter instance.
|
||||
*
|
||||
* @param algo encryption algorithm
|
||||
* @param key_size length of the key in bytes
|
||||
* @return crypter_t instance, NULL if not supported
|
||||
*/
|
||||
crypter_t* (*create_crypter)(crypto_factory_t *this,
|
||||
encryption_algorithm_t algo, size_t key_size);
|
||||
|
||||
/**
|
||||
* Create a symmetric signer instance.
|
||||
*
|
||||
* @param algo MAC algorithm to use
|
||||
* @return signer_t instance, NULL if not supported
|
||||
*/
|
||||
signer_t* (*create_signer)(crypto_factory_t *this,
|
||||
integrity_algorithm_t algo);
|
||||
|
||||
/**
|
||||
* Create a hasher instance.
|
||||
*
|
||||
* @param algo hash algorithm
|
||||
* @return hasher_t instance, NULL if not supported
|
||||
*/
|
||||
hasher_t* (*create_hasher)(crypto_factory_t *this, hash_algorithm_t algo);
|
||||
|
||||
/**
|
||||
* Create a pseudo random function instance.
|
||||
*
|
||||
* @param algo PRF algorithm to use
|
||||
* @return prf_t instance, NULL if not supported
|
||||
*/
|
||||
prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo);
|
||||
|
||||
/**
|
||||
* Create a diffie hellman instance.
|
||||
*
|
||||
* @param group diffie hellman group
|
||||
* @return diffie_hellman_t instance, NULL if not supported
|
||||
*/
|
||||
diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
|
||||
diffie_hellman_group_t group);
|
||||
|
||||
/**
|
||||
* Register a crypter constructor.
|
||||
*
|
||||
* @param algo algorithm to constructor
|
||||
* @param create constructor function for that algorithm
|
||||
* @return
|
||||
*/
|
||||
void (*add_crypter)(crypto_factory_t *this, encryption_algorithm_t algo,
|
||||
crypter_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a crypter constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a signer constructor.
|
||||
*
|
||||
* @param algo algorithm to constructor
|
||||
* @param create constructor function for that algorithm
|
||||
* @return
|
||||
*/
|
||||
void (*add_signer)(crypto_factory_t *this, integrity_algorithm_t algo,
|
||||
signer_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a signer constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_signer)(crypto_factory_t *this, signer_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a hasher constructor.
|
||||
*
|
||||
* The first added hasher is the preferred hasher returned on
|
||||
* create_hasher(HASH_PREFERRED).
|
||||
*
|
||||
* @param algo algorithm to constructor
|
||||
* @param create constructor function for that algorithm
|
||||
* @return
|
||||
*/
|
||||
void (*add_hasher)(crypto_factory_t *this, hash_algorithm_t algo,
|
||||
hasher_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a hasher constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_hasher)(crypto_factory_t *this, hasher_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a prf constructor.
|
||||
*
|
||||
* @param algo algorithm to constructor
|
||||
* @param create constructor function for that algorithm
|
||||
* @return
|
||||
*/
|
||||
void (*add_prf)(crypto_factory_t *this, pseudo_random_function_t algo,
|
||||
prf_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a prf constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create);
|
||||
|
||||
/**
|
||||
* Register a diffie hellman constructor.
|
||||
*
|
||||
* @param group dh group to constructor
|
||||
* @param create constructor function for that algorithm
|
||||
* @return
|
||||
*/
|
||||
void (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group,
|
||||
dh_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a diffie hellman constructor.
|
||||
*
|
||||
* @param create constructor function to unregister
|
||||
*/
|
||||
void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create);
|
||||
|
||||
/**
|
||||
* Destroy a crypto_factory instance.
|
||||
*/
|
||||
void (*destroy)(crypto_factory_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a crypto_factory instance.
|
||||
*/
|
||||
crypto_factory_t *crypto_factory_create();
|
||||
|
||||
#endif /* CRYPTO_FACTORY_H_ @}*/
|
||||
@@ -1,14 +1,5 @@
|
||||
/**
|
||||
* @file diffie_hellman.c
|
||||
*
|
||||
* @brief Implementation of diffie_hellman_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
|
||||
* Copyright (C) 1999, 2000, 2001 Henry Spencer.
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -21,15 +12,12 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <gmp.h>
|
||||
|
||||
#include "diffie_hellman.h"
|
||||
|
||||
#include <utils/randomizer.h>
|
||||
#include <debug.h>
|
||||
|
||||
ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT,
|
||||
"MODP_NONE",
|
||||
"MODP_768_BIT",
|
||||
@@ -44,546 +32,3 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BI
|
||||
"MODP_8192_BIT");
|
||||
ENUM_END(diffie_hellman_group_names, MODP_8192_BIT);
|
||||
|
||||
|
||||
/**
|
||||
* Modulus of Group 1 (MODP_768_BIT).
|
||||
*/
|
||||
static u_int8_t group1_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80 ,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 2 (MODP_1024_BIT).
|
||||
*/
|
||||
static u_int8_t group2_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 5 (MODP_1536_BIT).
|
||||
*/
|
||||
static u_int8_t group5_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
/**
|
||||
* Modulus of Group 14 (MODP_2048_BIT).
|
||||
*/
|
||||
static u_int8_t group14_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
|
||||
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
|
||||
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
|
||||
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
|
||||
0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 15 (MODP_3072_BIT).
|
||||
*/
|
||||
static u_int8_t group15_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
|
||||
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
|
||||
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
|
||||
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
|
||||
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
|
||||
0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
|
||||
0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
|
||||
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
|
||||
0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
|
||||
0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
|
||||
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
|
||||
0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
|
||||
0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 16 (MODP_4096_BIT).
|
||||
*/
|
||||
static u_int8_t group16_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
|
||||
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
|
||||
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
|
||||
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
|
||||
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
|
||||
0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
|
||||
0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
|
||||
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
|
||||
0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
|
||||
0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
|
||||
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
|
||||
0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
|
||||
0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
|
||||
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
|
||||
0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
|
||||
0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
|
||||
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
|
||||
0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
|
||||
0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
|
||||
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
|
||||
0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 17 (MODP_6144_BIT).
|
||||
*/
|
||||
static u_int8_t group17_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
|
||||
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
|
||||
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
|
||||
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
|
||||
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
|
||||
0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
|
||||
0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
|
||||
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
|
||||
0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
|
||||
0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
|
||||
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
|
||||
0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
|
||||
0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
|
||||
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
|
||||
0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
|
||||
0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
|
||||
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
|
||||
0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
|
||||
0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
|
||||
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
|
||||
0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
|
||||
0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
|
||||
0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
|
||||
0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
|
||||
0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
|
||||
0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
|
||||
0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
|
||||
0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
|
||||
0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
|
||||
0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
|
||||
0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
|
||||
0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
|
||||
0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
|
||||
0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
|
||||
0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
|
||||
0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
|
||||
0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Modulus of Group 18 (MODP_8192_BIT).
|
||||
*/
|
||||
static u_int8_t group18_modulus[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
|
||||
0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
|
||||
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
|
||||
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
|
||||
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
|
||||
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
|
||||
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
|
||||
0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
|
||||
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
|
||||
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
|
||||
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
|
||||
0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
|
||||
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
|
||||
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
|
||||
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
|
||||
0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
|
||||
0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
|
||||
0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
|
||||
0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
|
||||
0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
|
||||
0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
|
||||
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
|
||||
0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
|
||||
0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
|
||||
0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
|
||||
0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
|
||||
0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
|
||||
0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
|
||||
0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
|
||||
0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
|
||||
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
|
||||
0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
|
||||
0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
|
||||
0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
|
||||
0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
|
||||
0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
|
||||
0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
|
||||
0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
|
||||
0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
|
||||
0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
|
||||
0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
|
||||
0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
|
||||
0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
|
||||
0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
|
||||
0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
|
||||
0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
|
||||
0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
|
||||
0xE6,0x94,0xF9,0x1E,0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
|
||||
0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,0x73,0xB9,0x31,0xBA,
|
||||
0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,
|
||||
0x25,0x76,0xF6,0x93,0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
|
||||
0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,0xE3,0x9D,0x65,0x2D,
|
||||
0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,
|
||||
0x13,0xEB,0x57,0xA8,0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
|
||||
0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,0xA2,0xC0,0x87,0xE8,
|
||||
0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,
|
||||
0x6D,0x2A,0x13,0xF8,0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
|
||||
0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,0x08,0x46,0x85,0x1D,
|
||||
0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,
|
||||
0xFA,0xF3,0x6B,0xC3,0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
|
||||
0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
|
||||
0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
|
||||
0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
|
||||
0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
};
|
||||
|
||||
typedef struct modulus_entry_t modulus_entry_t;
|
||||
|
||||
/**
|
||||
* Entry of the modulus list.
|
||||
*/
|
||||
struct modulus_entry_t {
|
||||
/**
|
||||
* Group number as it is defined in file transform_substructure.h.
|
||||
*/
|
||||
diffie_hellman_group_t group;
|
||||
|
||||
/**
|
||||
* Pointer to first byte of modulus (network order).
|
||||
*/
|
||||
u_int8_t *modulus;
|
||||
|
||||
/*
|
||||
* Length of modulus in bytes.
|
||||
*/
|
||||
size_t modulus_len;
|
||||
|
||||
/*
|
||||
* Generator value.
|
||||
*/
|
||||
u_int16_t generator;
|
||||
};
|
||||
|
||||
/**
|
||||
* All supported modulus values.
|
||||
*/
|
||||
static modulus_entry_t modulus_entries[] = {
|
||||
{MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
|
||||
{MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
|
||||
{MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
|
||||
{MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
|
||||
{MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
|
||||
{MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
|
||||
{MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
|
||||
{MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
|
||||
};
|
||||
|
||||
typedef struct private_diffie_hellman_t private_diffie_hellman_t;
|
||||
|
||||
/**
|
||||
* Private data of an diffie_hellman_t object.
|
||||
*
|
||||
*/
|
||||
struct private_diffie_hellman_t {
|
||||
/**
|
||||
* Public diffie_hellman_t interface.
|
||||
*/
|
||||
diffie_hellman_t public;
|
||||
|
||||
/**
|
||||
* Diffie Hellman group number.
|
||||
*/
|
||||
u_int16_t group;
|
||||
|
||||
/*
|
||||
* Generator value.
|
||||
*/
|
||||
mpz_t g;
|
||||
|
||||
/**
|
||||
* My private value.
|
||||
*/
|
||||
mpz_t xa;
|
||||
|
||||
/**
|
||||
* My public value.
|
||||
*/
|
||||
mpz_t ya;
|
||||
|
||||
/**
|
||||
* Other public value.
|
||||
*/
|
||||
mpz_t yb;
|
||||
|
||||
/**
|
||||
* Shared secret.
|
||||
*/
|
||||
mpz_t zz;
|
||||
|
||||
/**
|
||||
* Modulus.
|
||||
*/
|
||||
mpz_t p;
|
||||
|
||||
/**
|
||||
* Modulus length.
|
||||
*/
|
||||
size_t p_len;
|
||||
|
||||
/**
|
||||
* True if shared secret is computed and stored in my_public_value.
|
||||
*/
|
||||
bool computed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.set_other_public_value.
|
||||
*/
|
||||
static void set_other_public_value(private_diffie_hellman_t *this, chunk_t value)
|
||||
{
|
||||
mpz_t p_min_1;
|
||||
|
||||
mpz_init(p_min_1);
|
||||
mpz_sub_ui(p_min_1, this->p, 1);
|
||||
|
||||
mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
|
||||
|
||||
/* check public value:
|
||||
* 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
|
||||
* 2. a public value larger or equal the modulus is invalid */
|
||||
if (mpz_cmp_ui(this->yb, 1) > 0 ||
|
||||
mpz_cmp(this->yb, p_min_1) < 0)
|
||||
{
|
||||
#ifdef EXTENDED_DH_TEST
|
||||
/* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
|
||||
mpz_t q, one;
|
||||
|
||||
mpz_init(q);
|
||||
mpz_init(one);
|
||||
mpz_fdiv_q_2exp(q, p_min_1, 1);
|
||||
mpz_powm(one, this->yb, q, this->p);
|
||||
mpz_clear(q);
|
||||
if (mpz_cmp_ui(one, 1) == 0)
|
||||
{
|
||||
mpz_powm(this->zz, this->yb, this->xa, this->p);
|
||||
this->computed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("public DH value verification failed: y ^ q mod p != 1");
|
||||
}
|
||||
mpz_clear(one);
|
||||
#else
|
||||
mpz_powm(this->zz, this->yb, this->xa, this->p);
|
||||
this->computed = TRUE;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
|
||||
}
|
||||
mpz_clear(p_min_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.get_other_public_value.
|
||||
*/
|
||||
static status_t get_other_public_value(private_diffie_hellman_t *this,
|
||||
chunk_t *value)
|
||||
{
|
||||
if (!this->computed)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
value->len = this->p_len;
|
||||
value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.get_my_public_value.
|
||||
*/
|
||||
static void get_my_public_value(private_diffie_hellman_t *this,chunk_t *value)
|
||||
{
|
||||
value->len = this->p_len;
|
||||
value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.get_shared_secret.
|
||||
*/
|
||||
static status_t get_shared_secret(private_diffie_hellman_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->computed)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
secret->len = this->p_len;
|
||||
secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.get_dh_group.
|
||||
*/
|
||||
static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the modulus in modulo table
|
||||
*/
|
||||
static status_t set_modulus(private_diffie_hellman_t *this)
|
||||
{
|
||||
int i;
|
||||
status_t status = NOT_FOUND;
|
||||
|
||||
for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
|
||||
{
|
||||
if (modulus_entries[i].group == this->group)
|
||||
{
|
||||
chunk_t chunk;
|
||||
chunk.ptr = modulus_entries[i].modulus;
|
||||
chunk.len = modulus_entries[i].modulus_len;
|
||||
mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
|
||||
this->p_len = chunk.len;
|
||||
mpz_set_ui(this->g, modulus_entries[i].generator);
|
||||
status = SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of diffie_hellman_t.destroy.
|
||||
*/
|
||||
static void destroy(private_diffie_hellman_t *this)
|
||||
{
|
||||
mpz_clear(this->p);
|
||||
mpz_clear(this->xa);
|
||||
mpz_clear(this->ya);
|
||||
mpz_clear(this->yb);
|
||||
mpz_clear(this->zz);
|
||||
mpz_clear(this->g);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group)
|
||||
{
|
||||
private_diffie_hellman_t *this = malloc_thing(private_diffie_hellman_t);
|
||||
randomizer_t *randomizer;
|
||||
chunk_t random;
|
||||
status_t status;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
|
||||
this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
|
||||
this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
|
||||
this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
|
||||
this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
|
||||
this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
|
||||
|
||||
/* private variables */
|
||||
this->group = group;
|
||||
mpz_init(this->p);
|
||||
mpz_init(this->yb);
|
||||
mpz_init(this->ya);
|
||||
mpz_init(this->xa);
|
||||
mpz_init(this->zz);
|
||||
mpz_init(this->g);
|
||||
|
||||
this->computed = FALSE;
|
||||
|
||||
/* find a modulus according to group */
|
||||
if (set_modulus(this) != SUCCESS)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
randomizer = randomizer_create();
|
||||
status = randomizer->allocate_pseudo_random_bytes(
|
||||
randomizer, this->p_len, &random);
|
||||
randomizer->destroy(randomizer);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
|
||||
chunk_free(&random);
|
||||
|
||||
mpz_powm(this->ya, this->g, this->xa, this->p);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file diffie_hellman.h
|
||||
*
|
||||
* @brief Interface of diffie_hellman_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup diffie_hellman diffie_hellman
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef DIFFIE_HELLMAN_H_
|
||||
@@ -30,13 +30,10 @@ typedef struct diffie_hellman_t diffie_hellman_t;
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief Diffie-Hellman group.
|
||||
* Diffie-Hellman group.
|
||||
*
|
||||
* The modulus (or group) to use for a Diffie-Hellman calculation.
|
||||
*
|
||||
* See IKEv2 RFC 3.3.2 and RFC 3526.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
enum diffie_hellman_group_t {
|
||||
MODP_NONE = 0,
|
||||
@@ -56,89 +53,60 @@ enum diffie_hellman_group_t {
|
||||
extern enum_name_t *diffie_hellman_group_names;
|
||||
|
||||
/**
|
||||
* @brief Implementation of the Diffie-Hellman algorithm, as in RFC2631.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - diffie_hellman_create()
|
||||
*
|
||||
* @ingroup crypto
|
||||
* Implementation of the Diffie-Hellman algorithm, as in RFC2631.
|
||||
*/
|
||||
struct diffie_hellman_t {
|
||||
|
||||
/**
|
||||
* @brief Returns the shared secret of this diffie hellman exchange.
|
||||
* Returns the shared secret of this diffie hellman exchange.
|
||||
*
|
||||
* Space for returned secret is allocated and must be
|
||||
* freed by the caller.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param secret shared secret will be written into this chunk
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if not both DH values are set
|
||||
* @return SUCCESS, FAILED if not both DH values are set
|
||||
*/
|
||||
status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
|
||||
|
||||
/**
|
||||
* @brief Sets the public value of partner.
|
||||
* Sets the public value of partner.
|
||||
*
|
||||
* Chunk gets cloned and can be destroyed afterwards.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param value public value of partner
|
||||
*/
|
||||
void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* @brief Gets the public value of partner.
|
||||
* Gets the public value of partner.
|
||||
*
|
||||
* Space for returned chunk is allocated and must be freed by the caller.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param value public value of partner is stored at this location
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if other public value not set
|
||||
* @return SUCCESS, FAILED if other public value not set
|
||||
*/
|
||||
status_t (*get_other_public_value) (diffie_hellman_t *this, chunk_t *value);
|
||||
|
||||
/**
|
||||
* @brief Gets the own public value to transmit.
|
||||
* Gets the own public value to transmit.
|
||||
*
|
||||
* Space for returned chunk is allocated and must be freed by the caller.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param value public value of caller is stored at this location
|
||||
*/
|
||||
void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
|
||||
|
||||
/**
|
||||
* @brief Get the DH group used.
|
||||
* Get the DH group used.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return DH group set in construction
|
||||
*/
|
||||
diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an diffie_hellman_t object.
|
||||
*
|
||||
* @param this diffie_hellman_t object to destroy
|
||||
* Destroys an diffie_hellman_t object.
|
||||
*/
|
||||
void (*destroy) (diffie_hellman_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a new diffie_hellman_t object.
|
||||
*
|
||||
* @param group Diffie Hellman group number to use
|
||||
* @return
|
||||
* - diffie_hellman_t object
|
||||
* - NULL if dh group not supported
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group);
|
||||
|
||||
#endif /*DIFFIE_HELLMAN_H_*/
|
||||
|
||||
#endif /*DIFFIE_HELLMAN_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file hasher.c
|
||||
*
|
||||
* @brief Generic constructor for hasher_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
@@ -21,91 +14,53 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include "hasher.h"
|
||||
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/hashers/sha1_hasher.h>
|
||||
#include <crypto/hashers/sha2_hasher.h>
|
||||
#include <crypto/hashers/md5_hasher.h>
|
||||
|
||||
|
||||
ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
|
||||
"HASH_UNKNOWN",
|
||||
"HASH_PREFERRED",
|
||||
"HASH_MD2",
|
||||
"HASH_MD5",
|
||||
"HASH_SHA1",
|
||||
"HASH_SHA1_NOFINAL",
|
||||
"HASH_SHA256",
|
||||
"HASH_SHA384",
|
||||
"HASH_SHA512"
|
||||
);
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
hasher_t *hasher_create(hash_algorithm_t hash_algorithm)
|
||||
{
|
||||
switch (hash_algorithm)
|
||||
{
|
||||
case HASH_SHA1:
|
||||
{
|
||||
return (hasher_t*)sha1_hasher_create();
|
||||
}
|
||||
case HASH_SHA256:
|
||||
case HASH_SHA384:
|
||||
case HASH_SHA512:
|
||||
{
|
||||
return (hasher_t*)sha2_hasher_create(hash_algorithm);
|
||||
}
|
||||
case HASH_MD5:
|
||||
{
|
||||
return (hasher_t*)md5_hasher_create();
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
hash_algorithm_t hasher_algorithm_from_oid(int oid)
|
||||
{
|
||||
hash_algorithm_t algorithm;
|
||||
|
||||
switch (oid)
|
||||
{
|
||||
case OID_MD2:
|
||||
case OID_MD2_WITH_RSA:
|
||||
algorithm = HASH_MD2;
|
||||
break;
|
||||
return HASH_MD2;
|
||||
case OID_MD5:
|
||||
case OID_MD5_WITH_RSA:
|
||||
algorithm = HASH_MD5;
|
||||
break;
|
||||
return HASH_MD5;
|
||||
case OID_SHA1:
|
||||
case OID_SHA1_WITH_RSA:
|
||||
algorithm = HASH_SHA1;
|
||||
break;
|
||||
return HASH_SHA1;
|
||||
case OID_SHA256:
|
||||
case OID_SHA256_WITH_RSA:
|
||||
algorithm = HASH_SHA256;
|
||||
break;
|
||||
return HASH_SHA256;
|
||||
case OID_SHA384:
|
||||
case OID_SHA384_WITH_RSA:
|
||||
algorithm = HASH_SHA384;
|
||||
break;
|
||||
return HASH_SHA384;
|
||||
case OID_SHA512:
|
||||
case OID_SHA512_WITH_RSA:
|
||||
algorithm = HASH_SHA512;
|
||||
break;
|
||||
return HASH_SHA512;
|
||||
default:
|
||||
algorithm = HASH_UNKNOWN;
|
||||
return HASH_UNKNOWN;
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file hasher.h
|
||||
*
|
||||
* @brief Interface hasher_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
@@ -21,7 +14,12 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup traffic_selector traffic_selector
|
||||
* @{ @ingroup config
|
||||
*/
|
||||
|
||||
#ifndef HASHER_H_
|
||||
@@ -33,30 +31,21 @@ typedef struct hasher_t hasher_t;
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief Algorithms to use for hashing.
|
||||
*
|
||||
* Currently only the following algorithms are implemented:
|
||||
* - HASH_MD5
|
||||
* - HASH_SHA1
|
||||
* - HASH_SHA256
|
||||
* - HASH_SHA384
|
||||
* - HASH_SHA512
|
||||
*
|
||||
* @ingroup hashers
|
||||
* Algorithms to use for hashing.
|
||||
*/
|
||||
enum hash_algorithm_t {
|
||||
HASH_UNKNOWN = 0,
|
||||
HASH_MD2 = 1,
|
||||
/** Implemented in class md5_hasher_t */
|
||||
HASH_MD5 = 2,
|
||||
/** Implemented in class sha1_hasher_t */
|
||||
HASH_SHA1 = 3,
|
||||
/** Implemented in class sha2_hasher_t */
|
||||
HASH_SHA256 = 4,
|
||||
/** Implemented in class sha2_hasher_t */
|
||||
HASH_SHA384 = 5,
|
||||
/** Implemented in class sha2_hasher_t */
|
||||
HASH_SHA512 = 6,
|
||||
/** not specified hash function */
|
||||
HASH_UNKNOWN = 0,
|
||||
/** preferred hash function, general purpose */
|
||||
HASH_PREFERRED = 1,
|
||||
HASH_MD2 = 2,
|
||||
HASH_MD5 = 3,
|
||||
HASH_SHA1 = 4,
|
||||
/** special SHA1 which does not run SHA1Final, but copies the state */
|
||||
HASH_SHA1_NOFINAL = 5,
|
||||
HASH_SHA256 = 6,
|
||||
HASH_SHA384 = 7,
|
||||
HASH_SHA512 = 8,
|
||||
};
|
||||
|
||||
#define HASH_SIZE_MD2 16
|
||||
@@ -65,7 +54,6 @@ enum hash_algorithm_t {
|
||||
#define HASH_SIZE_SHA256 32
|
||||
#define HASH_SIZE_SHA384 48
|
||||
#define HASH_SIZE_SHA512 64
|
||||
#define HASH_SIZE_MAX 64
|
||||
|
||||
/**
|
||||
* enum names for hash_algorithm_t.
|
||||
@@ -73,16 +61,11 @@ enum hash_algorithm_t {
|
||||
extern enum_name_t *hash_algorithm_names;
|
||||
|
||||
/**
|
||||
* @brief Generic interface for all hash functions.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - hasher_create()
|
||||
*
|
||||
* @ingroup hashers
|
||||
* Generic interface for all hash functions.
|
||||
*/
|
||||
struct hasher_t {
|
||||
/**
|
||||
* @brief Hash data and write it in the buffer.
|
||||
* Hash data and write it in the buffer.
|
||||
*
|
||||
* If the parameter hash is NULL, no result is written back
|
||||
* and more data can be appended to already hashed data.
|
||||
@@ -91,108 +74,63 @@ struct hasher_t {
|
||||
* The hash output parameter must hold at least
|
||||
* hash_t.get_block_size() bytes.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to hash
|
||||
* @param[out] hash pointer where the hash will be written
|
||||
* @param data data to hash
|
||||
* @param hash pointer where the hash will be written
|
||||
*/
|
||||
void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
|
||||
|
||||
/**
|
||||
* @brief Hash data and allocate space for the hash.
|
||||
* Hash data and allocate space for the hash.
|
||||
*
|
||||
* If the parameter hash is NULL, no result is written back
|
||||
* and more data can be appended to already hashed data.
|
||||
* If not, the result is written back and the hasher is reset.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data chunk with data to hash
|
||||
* @param[out] hash chunk which will hold allocated hash
|
||||
* @param data chunk with data to hash
|
||||
* @param hash chunk which will hold allocated hash
|
||||
*/
|
||||
void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash);
|
||||
|
||||
/**
|
||||
* @brief Get the size of the resulting hash.
|
||||
* Get the size of the resulting hash.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return hash size in bytes
|
||||
* @return hash size in bytes
|
||||
*/
|
||||
size_t (*get_hash_size) (hasher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Resets the hashers state.
|
||||
*
|
||||
* @param this calling object
|
||||
* Resets the hashers state.
|
||||
*/
|
||||
void (*reset) (hasher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the state of the hasher.
|
||||
*
|
||||
* A hasher stores internal state information. This state may be
|
||||
* manipulated to include a "seed" into the hashing operation. It used by
|
||||
* some exotic protocols (such as AKA).
|
||||
* The data pointed by chunk may be manipulated, but not replaced nor freed.
|
||||
* This is more a hack than a feature. The hasher's state may be byte
|
||||
* order dependant; use with care.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
chunk_t (*get_state) (hasher_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a hasher object.
|
||||
*
|
||||
* @param this calling object
|
||||
* Destroys a hasher object.
|
||||
*/
|
||||
void (*destroy) (hasher_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generic interface to create a hasher_t.
|
||||
* Conversion of ASN.1 OID to hash algorithm.
|
||||
*
|
||||
* @param hash_algorithm Algorithm to use for hashing
|
||||
* @return
|
||||
* - hasher_t object
|
||||
* - NULL if algorithm not supported
|
||||
*
|
||||
* @ingroup hashers
|
||||
*/
|
||||
hasher_t *hasher_create(hash_algorithm_t hash_algorithm);
|
||||
|
||||
/**
|
||||
* @brief Conversion of ASN.1 OID to hash algorithm.
|
||||
*
|
||||
* @param oid ASN.1 OID
|
||||
* @return
|
||||
* - hash algorithm
|
||||
* - HASH_UNKNOWN if OID unsuported
|
||||
*
|
||||
* @ingroup hashers
|
||||
* @param oid ASN.1 OID
|
||||
* @return hash algorithm, HASH_UNKNOWN if OID unsuported
|
||||
*/
|
||||
hash_algorithm_t hasher_algorithm_from_oid(int oid);
|
||||
|
||||
/**
|
||||
* @brief Conversion of hash algorithm into ASN.1 OID.
|
||||
* Conversion of hash algorithm into ASN.1 OID.
|
||||
*
|
||||
* @param alg hash algorithm
|
||||
* @return
|
||||
* - ASN.1 hash OID if known hash algorithm
|
||||
* - OID_UNKNOW
|
||||
*
|
||||
* @ingroup hashers
|
||||
* @param alg hash algorithm
|
||||
* @return ASN.1 OID, or OID_UNKNOW
|
||||
*/
|
||||
int hasher_algorithm_to_oid(hash_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Conversion of hash signature algorithm into ASN.1 OID.
|
||||
* Conversion of hash signature algorithm into ASN.1 OID.
|
||||
*
|
||||
* @param alg hash algorithm
|
||||
* @return
|
||||
* - ASN.1 signature OID if known hash algorithm
|
||||
* - OID_UNKNOW
|
||||
*
|
||||
* @ingroup hashers
|
||||
* @param alg hash algorithm
|
||||
* @return ASN.1 OID if, or OID_UNKNOW
|
||||
*/
|
||||
int hasher_signature_algorithm_to_oid(hash_algorithm_t alg);
|
||||
|
||||
#endif /* HASHER_H_ */
|
||||
#endif /* HASHER_H_ @} */
|
||||
|
||||
@@ -1,405 +0,0 @@
|
||||
/**
|
||||
* @file ietf_attr.c
|
||||
*
|
||||
* @brief Implementation of ietfAttr_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <utils/lexparser.h>
|
||||
|
||||
#include "ietf_attr_list.h"
|
||||
|
||||
/**
|
||||
* Private definition of ietfAttribute kinds
|
||||
*/
|
||||
typedef enum {
|
||||
IETF_ATTRIBUTE_OCTETS = 0,
|
||||
IETF_ATTRIBUTE_OID = 1,
|
||||
IETF_ATTRIBUTE_STRING = 2
|
||||
} ietfAttribute_t;
|
||||
|
||||
typedef struct ietfAttr_t ietfAttr_t;
|
||||
|
||||
/**
|
||||
* Private definition of an ietfAttribute
|
||||
*/
|
||||
struct ietfAttr_t {
|
||||
/**
|
||||
* IETF attribute kind
|
||||
*/
|
||||
ietfAttribute_t kind;
|
||||
|
||||
/**
|
||||
* IETF attribute valuse
|
||||
*/
|
||||
chunk_t value;
|
||||
|
||||
/**
|
||||
* Compares two ietfAttributes
|
||||
*
|
||||
* return -1 if this is earlier in the alphabet than other
|
||||
* return 0 if this equals other
|
||||
* return +1 if this is later in the alphabet than other
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other other object
|
||||
*/
|
||||
int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
|
||||
|
||||
/**
|
||||
* Destroys the ietfAttr_t object.
|
||||
*
|
||||
* @param this ietfAttr_t to destroy
|
||||
*/
|
||||
void (*destroy) (ietfAttr_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements ietfAttr_t.compare.
|
||||
*/
|
||||
static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
|
||||
{
|
||||
int cmp_len, len, cmp_value;
|
||||
|
||||
/* OID attributes are appended after STRING and OCTETS attributes */
|
||||
if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
cmp_len = this->value.len - other->value.len;
|
||||
len = (cmp_len < 0)? this->value.len : other->value.len;
|
||||
cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
|
||||
|
||||
return (cmp_value == 0)? cmp_len : cmp_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ietfAttr_t.destroy.
|
||||
*/
|
||||
static void ietfAttr_destroy(ietfAttr_t *this)
|
||||
{
|
||||
free(this->value.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ietfAttr_t object.
|
||||
*/
|
||||
static ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
|
||||
{
|
||||
ietfAttr_t *this = malloc_thing(ietfAttr_t);
|
||||
|
||||
/* initialize */
|
||||
this->kind = kind;
|
||||
this->value = chunk_clone(value);
|
||||
|
||||
/* function */
|
||||
this->compare = ietfAttr_compare;
|
||||
this->destroy = ietfAttr_destroy;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ietfAttr_t object to a sorted linked list
|
||||
*/
|
||||
static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
|
||||
{
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
ietfAttr_t *current_attr;
|
||||
bool found = FALSE;
|
||||
|
||||
while (iterator->iterate(iterator, (void **)¤t_attr))
|
||||
{
|
||||
int cmp = attr->compare(attr, current_attr);
|
||||
|
||||
if (cmp > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (cmp == 0)
|
||||
{
|
||||
attr->destroy(attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->insert_before(iterator, attr);
|
||||
}
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
if (!found)
|
||||
{
|
||||
list->insert_last(list, attr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b)
|
||||
{
|
||||
bool result = TRUE;
|
||||
|
||||
/* lists must have the same number of attributes */
|
||||
if (list_a->get_count(list_a) != list_b->get_count(list_b))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* empty lists - no attributes */
|
||||
if (list_a->get_count(list_a) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* compare two alphabetically-sorted lists */
|
||||
{
|
||||
iterator_t *iterator_a = list_a->create_iterator(list_a, TRUE);
|
||||
iterator_t *iterator_b = list_b->create_iterator(list_b, TRUE);
|
||||
ietfAttr_t *attr_a, *attr_b;
|
||||
|
||||
while (iterator_a->iterate(iterator_a, (void **)&attr_a) &&
|
||||
iterator_b->iterate(iterator_b, (void **)&attr_b))
|
||||
{
|
||||
if (attr_a->compare(attr_a, attr_b) != 0)
|
||||
{
|
||||
/* we have a mismatch */
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator_a->destroy(iterator_a);
|
||||
iterator_b->destroy(iterator_b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ietfAttr_list_list(linked_list_t *list, FILE *out)
|
||||
{
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
ietfAttr_t *attr;
|
||||
bool first = TRUE;
|
||||
|
||||
while (iterator->iterate(iterator, (void **)&attr))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, ", ");
|
||||
}
|
||||
|
||||
switch (attr->kind)
|
||||
{
|
||||
case IETF_ATTRIBUTE_OCTETS:
|
||||
case IETF_ATTRIBUTE_STRING:
|
||||
fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
|
||||
break;
|
||||
case IETF_ATTRIBUTE_OID:
|
||||
{
|
||||
int oid = known_oid(attr->value);
|
||||
|
||||
if (oid == OID_UNKNOWN)
|
||||
{
|
||||
fprintf(out, "0x#B", &attr->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "%s", oid_names[oid]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ietfAttr_list_create_from_string(char *msg, linked_list_t *list)
|
||||
{
|
||||
chunk_t line = { msg, strlen(msg) };
|
||||
|
||||
while (eat_whitespace(&line))
|
||||
{
|
||||
chunk_t group;
|
||||
|
||||
/* extract the next comma-separated group attribute */
|
||||
if (!extract_token(&group, ',', &line))
|
||||
{
|
||||
group = line;
|
||||
line.len = 0;
|
||||
}
|
||||
|
||||
/* remove any trailing spaces */
|
||||
while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
|
||||
{
|
||||
group.len--;
|
||||
}
|
||||
|
||||
/* add the group attribute to the list */
|
||||
if (group.len > 0)
|
||||
{
|
||||
ietfAttr_t *attr = ietfAttr_create(IETF_ATTRIBUTE_STRING, group);
|
||||
|
||||
ietfAttr_add(list, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ASN.1 definition of ietfAttrSyntax
|
||||
*/
|
||||
static const asn1Object_t ietfAttrSyntaxObjects[] =
|
||||
{
|
||||
{ 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
|
||||
{ 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
|
||||
ASN1_BODY }, /* 1 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
|
||||
{ 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
|
||||
{ 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
|
||||
ASN1_BODY }, /* 4 */
|
||||
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
|
||||
{ 2, "oid", ASN1_OID, ASN1_OPT |
|
||||
ASN1_BODY }, /* 6 */
|
||||
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
|
||||
{ 2, "string", ASN1_UTF8STRING, ASN1_OPT |
|
||||
ASN1_BODY }, /* 8 */
|
||||
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
|
||||
{ 1, "end loop", ASN1_EOC, ASN1_END } /* 10 */
|
||||
};
|
||||
|
||||
#define IETF_ATTR_OCTETS 4
|
||||
#define IETF_ATTR_OID 6
|
||||
#define IETF_ATTR_STRING 8
|
||||
#define IETF_ATTR_ROOF 11
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
|
||||
asn1_init(&ctx, chunk, level0, FALSE, FALSE);
|
||||
|
||||
while (objectID < IETF_ATTR_ROOF)
|
||||
{
|
||||
if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case IETF_ATTR_OCTETS:
|
||||
case IETF_ATTR_OID:
|
||||
case IETF_ATTR_STRING:
|
||||
{
|
||||
ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
|
||||
ietfAttr_t *attr = ietfAttr_create(kind, object);
|
||||
ietfAttr_add(list, attr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
chunk_t ietfAttr_list_encode(linked_list_t *list)
|
||||
{
|
||||
chunk_t ietfAttributes;
|
||||
size_t size = 0;
|
||||
u_char *pos;
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
ietfAttr_t *attr;
|
||||
|
||||
/* precalculate the total size of all values */
|
||||
while (iterator->iterate(iterator, (void **)&attr))
|
||||
{
|
||||
size_t len = attr->value.len;
|
||||
|
||||
size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
|
||||
|
||||
iterator = list->create_iterator(list, TRUE);
|
||||
while (iterator->iterate(iterator, (void **)&attr))
|
||||
{
|
||||
chunk_t ietfAttribute;
|
||||
asn1_t type = ASN1_NULL;
|
||||
|
||||
switch (attr->kind)
|
||||
{
|
||||
case IETF_ATTRIBUTE_OCTETS:
|
||||
type = ASN1_OCTET_STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_STRING:
|
||||
type = ASN1_UTF8STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_OID:
|
||||
type = ASN1_OID;
|
||||
break;
|
||||
}
|
||||
ietfAttribute = asn1_simple_object(type, attr->value);
|
||||
|
||||
/* copy ietfAttribute into ietfAttributes chunk */
|
||||
memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
|
||||
pos += ietfAttribute.len;
|
||||
free(ietfAttribute.ptr);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
void ietfAttr_list_destroy(linked_list_t *list)
|
||||
{
|
||||
list->destroy_offset(list, offsetof(ietfAttr_t, destroy));
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* @file ietf_attr_list.h
|
||||
*
|
||||
* @brief Handling of ietfAttr_t linked lists
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IETF_ATTR_LIST_H_
|
||||
#define IETF_ATTR_LIST_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Compare two linked lists of ietfAttr_t objects for equality
|
||||
*
|
||||
* @param list_a first alphabetically-sorted list
|
||||
* @param list_b second alphabetically-sorted list
|
||||
* @return TRUE if equal
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
|
||||
|
||||
/**
|
||||
* @brief Lists a linked list of ietfAttr_t objects
|
||||
*
|
||||
* @param list alphabetically-sorted linked list of attributes
|
||||
@param out output file
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void ietfAttr_list_list(linked_list_t *list, FILE *out);
|
||||
|
||||
/**
|
||||
* @brief Create a linked list of ietfAttr_t objects from a string
|
||||
*
|
||||
* @param msg string with comma-separated group names
|
||||
* @param list alphabetically-sorted linked list of attributes
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
|
||||
|
||||
/**
|
||||
* @brief Create a linked list of ietfAttr_t objects from an ASN.1-coded chunk
|
||||
*
|
||||
* @param chunk chunk containing ASN.1-coded attributes
|
||||
* @param list alphabetically-sorted linked list of attributes
|
||||
* @param level0 parsing level
|
||||
*/
|
||||
void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
|
||||
|
||||
/**
|
||||
* @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
|
||||
*
|
||||
* @param list alphabetically-sorted linked list of attributes
|
||||
* @return chunk containing ASN.1-coded attributes
|
||||
*/
|
||||
chunk_t ietfAttr_list_encode(linked_list_t *list);
|
||||
|
||||
/**
|
||||
* @brief Destroys a linked list of ietfAttr_t objects
|
||||
*
|
||||
* @param list list to be destroyed
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void ietfAttr_list_destroy(linked_list_t *list);
|
||||
|
||||
#endif /* IETF_ATTR_LIST_H_ */
|
||||
|
||||
@@ -1,934 +0,0 @@
|
||||
/**
|
||||
* @file ocsp.c
|
||||
*
|
||||
* @brief Implementation of ocsp_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Support of the Online Certificate Status Protocol (OCSP)
|
||||
*
|
||||
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
*
|
||||
* Hochschule für Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <asn1/oid.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/randomizer.h>
|
||||
#include <utils/fetcher.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "hashers/hasher.h"
|
||||
#include "rsa/rsa_public_key.h"
|
||||
#include "certinfo.h"
|
||||
#include "x509.h"
|
||||
#include "ocsp.h"
|
||||
|
||||
#define NONCE_LENGTH 16
|
||||
|
||||
typedef struct private_ocsp_t private_ocsp_t;
|
||||
|
||||
/**
|
||||
* Private data of a ocsp_t object.
|
||||
*/
|
||||
struct private_ocsp_t {
|
||||
/**
|
||||
* Public interface for this ocsp object.
|
||||
*/
|
||||
ocsp_t public;
|
||||
|
||||
/**
|
||||
* CA certificate.
|
||||
*/
|
||||
x509_t *cacert;
|
||||
|
||||
/**
|
||||
* Requestor certificate
|
||||
*/
|
||||
x509_t *requestor_cert;
|
||||
|
||||
/**
|
||||
* Linked list of ocsp uris
|
||||
*/
|
||||
linked_list_t *uris;
|
||||
|
||||
/**
|
||||
* Linked list of certinfos to be requested
|
||||
*/
|
||||
linked_list_t *certinfos;
|
||||
|
||||
/**
|
||||
* Nonce required for ocsp request and response
|
||||
*/
|
||||
chunk_t nonce;
|
||||
|
||||
/**
|
||||
* SHA-1 hash over issuer distinguished name
|
||||
*/
|
||||
chunk_t authNameID;
|
||||
|
||||
/**
|
||||
* SHA-1 hash over issuer public key
|
||||
*/
|
||||
chunk_t authKeyID;
|
||||
};
|
||||
|
||||
ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
|
||||
"successful",
|
||||
"malformed request",
|
||||
"internal error",
|
||||
"try later",
|
||||
"signature required",
|
||||
"unauthorized"
|
||||
);
|
||||
|
||||
/* response container */
|
||||
typedef struct response_t response_t;
|
||||
|
||||
struct response_t {
|
||||
chunk_t chunk;
|
||||
chunk_t tbs;
|
||||
identification_t *responder_id_name;
|
||||
chunk_t responder_id_key;
|
||||
time_t produced_at;
|
||||
chunk_t responses;
|
||||
chunk_t nonce;
|
||||
int algorithm;
|
||||
chunk_t signature;
|
||||
x509_t *responder_cert;
|
||||
|
||||
/**
|
||||
* @brief Destroys the response_t object
|
||||
*
|
||||
* @param this response_t to destroy
|
||||
*/
|
||||
void (*destroy) (response_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements response_t.destroy.
|
||||
*/
|
||||
static void response_destroy(response_t *this)
|
||||
{
|
||||
DESTROY_IF(this->responder_id_name);
|
||||
DESTROY_IF(this->responder_cert);
|
||||
free(this->chunk.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a response_t object
|
||||
*/
|
||||
static response_t* response_create_from_chunk(chunk_t chunk)
|
||||
{
|
||||
response_t *this = malloc_thing(response_t);
|
||||
|
||||
this->chunk = chunk;
|
||||
this->tbs = chunk_empty;
|
||||
this->responder_id_name = NULL;
|
||||
this->responder_id_key = chunk_empty;
|
||||
this->produced_at = UNDEFINED_TIME;
|
||||
this->responses = chunk_empty;
|
||||
this->nonce = chunk_empty;
|
||||
this->algorithm = OID_UNKNOWN;
|
||||
this->signature = chunk_empty;
|
||||
this->responder_cert = NULL;
|
||||
|
||||
this->destroy = (void (*) (response_t*))response_destroy;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/* some OCSP specific prefabricated ASN.1 constants */
|
||||
|
||||
static u_char ASN1_nonce_oid_str[] = {
|
||||
0x06, 0x09,
|
||||
0x2B, 0x06,
|
||||
0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
|
||||
};
|
||||
|
||||
static u_char ASN1_response_oid_str[] = {
|
||||
0x06, 0x09,
|
||||
0x2B, 0x06,
|
||||
0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
|
||||
};
|
||||
|
||||
static u_char ASN1_response_content_str[] = {
|
||||
0x04, 0x0D,
|
||||
0x30, 0x0B,
|
||||
0x06, 0x09,
|
||||
0x2B, 0x06,
|
||||
0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
|
||||
};
|
||||
|
||||
static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
|
||||
static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
|
||||
static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
|
||||
|
||||
/* asn.1 definitions for parsing */
|
||||
|
||||
static const asn1Object_t ocspResponseObjects[] = {
|
||||
{ 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
|
||||
{ 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
|
||||
{ 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
|
||||
{ 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
|
||||
{ 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
|
||||
{ 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
|
||||
};
|
||||
|
||||
#define OCSP_RESPONSE_STATUS 1
|
||||
#define OCSP_RESPONSE_TYPE 4
|
||||
#define OCSP_RESPONSE 5
|
||||
#define OCSP_RESPONSE_ROOF 7
|
||||
|
||||
static const asn1Object_t basicResponseObjects[] = {
|
||||
{ 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
|
||||
{ 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
|
||||
{ 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
|
||||
ASN1_DEF }, /* 2 */
|
||||
{ 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
|
||||
{ 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
|
||||
{ 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
|
||||
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
|
||||
{ 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
|
||||
{ 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
|
||||
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
|
||||
{ 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
|
||||
{ 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
|
||||
{ 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
|
||||
{ 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
|
||||
{ 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
|
||||
{ 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
|
||||
{ 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
|
||||
ASN1_DEF }, /* 16 */
|
||||
{ 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
|
||||
{ 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
|
||||
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
|
||||
{ 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
|
||||
{ 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
|
||||
{ 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
|
||||
{ 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
|
||||
{ 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
|
||||
{ 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
|
||||
};
|
||||
|
||||
#define BASIC_RESPONSE_TBS_DATA 1
|
||||
#define BASIC_RESPONSE_VERSION 3
|
||||
#define BASIC_RESPONSE_ID_BY_NAME 5
|
||||
#define BASIC_RESPONSE_ID_BY_KEY 8
|
||||
#define BASIC_RESPONSE_PRODUCED_AT 10
|
||||
#define BASIC_RESPONSE_RESPONSES 11
|
||||
#define BASIC_RESPONSE_EXT_ID 15
|
||||
#define BASIC_RESPONSE_CRITICAL 16
|
||||
#define BASIC_RESPONSE_EXT_VALUE 17
|
||||
#define BASIC_RESPONSE_ALGORITHM 20
|
||||
#define BASIC_RESPONSE_SIGNATURE 21
|
||||
#define BASIC_RESPONSE_CERTIFICATE 24
|
||||
#define BASIC_RESPONSE_ROOF 27
|
||||
|
||||
static const asn1Object_t responsesObjects[] = {
|
||||
{ 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
|
||||
{ 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
|
||||
{ 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
|
||||
};
|
||||
|
||||
#define RESPONSES_SINGLE_RESPONSE 1
|
||||
#define RESPONSES_ROOF 3
|
||||
|
||||
static const asn1Object_t singleResponseObjects[] = {
|
||||
{ 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
|
||||
{ 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
|
||||
{ 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
|
||||
{ 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
|
||||
{ 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
|
||||
{ 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
|
||||
{ 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
|
||||
{ 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
|
||||
{ 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
|
||||
{ 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
|
||||
{ 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
|
||||
{ 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
|
||||
{ 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
|
||||
{ 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
|
||||
{ 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
|
||||
{ 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
|
||||
{ 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
|
||||
{ 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
|
||||
{ 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
|
||||
{ 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
|
||||
{ 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
|
||||
ASN1_DEF }, /* 24 */
|
||||
{ 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
|
||||
{ 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
|
||||
{ 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
|
||||
};
|
||||
|
||||
#define SINGLE_RESPONSE_ALGORITHM 2
|
||||
#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
|
||||
#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
|
||||
#define SINGLE_RESPONSE_SERIAL_NUMBER 5
|
||||
#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
|
||||
#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
|
||||
#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
|
||||
#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
|
||||
#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
|
||||
#define SINGLE_RESPONSE_THIS_UPDATE 16
|
||||
#define SINGLE_RESPONSE_NEXT_UPDATE 18
|
||||
#define SINGLE_RESPONSE_EXT_ID 23
|
||||
#define SINGLE_RESPONSE_CRITICAL 24
|
||||
#define SINGLE_RESPONSE_EXT_VALUE 25
|
||||
#define SINGLE_RESPONSE_ROOF 28
|
||||
|
||||
/**
|
||||
* build requestorName (into TBSRequest)
|
||||
*/
|
||||
static chunk_t build_requestor_name(private_ocsp_t *this)
|
||||
{
|
||||
identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert);
|
||||
|
||||
return asn1_wrap(ASN1_CONTEXT_C_1, "m",
|
||||
asn1_simple_object(ASN1_CONTEXT_C_4,
|
||||
requestor_name->get_encoding(requestor_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* build request (into requestList)
|
||||
* no singleRequestExtensions used
|
||||
*/
|
||||
static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
|
||||
{
|
||||
chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
|
||||
|
||||
chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
|
||||
asn1_algorithmIdentifier(OID_SHA1),
|
||||
asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
|
||||
asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID),
|
||||
asn1_simple_object(ASN1_INTEGER, serialNumber));
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
|
||||
}
|
||||
|
||||
/**
|
||||
* build requestList (into TBSRequest)
|
||||
*/
|
||||
static chunk_t build_request_list(private_ocsp_t *this)
|
||||
{
|
||||
chunk_t requestList;
|
||||
size_t datalen = 0;
|
||||
linked_list_t *request_list = linked_list_create();
|
||||
|
||||
{
|
||||
iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
|
||||
certinfo_t *certinfo;
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&certinfo))
|
||||
{
|
||||
chunk_t *request = malloc_thing(chunk_t);
|
||||
|
||||
*request = build_request(this, certinfo);
|
||||
request_list->insert_last(request_list, (void*)request);
|
||||
datalen += request->len;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
{
|
||||
iterator_t *iterator = request_list->create_iterator(request_list, TRUE);
|
||||
chunk_t *request;
|
||||
|
||||
u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen);
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&request))
|
||||
{
|
||||
memcpy(pos, request->ptr, request->len);
|
||||
pos += request->len;
|
||||
free(request->ptr);
|
||||
free(request);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
request_list->destroy(request_list);
|
||||
}
|
||||
return requestList;
|
||||
}
|
||||
|
||||
/**
|
||||
* build nonce extension (into requestExtensions)
|
||||
*/
|
||||
static chunk_t build_nonce_extension(private_ocsp_t *this)
|
||||
{
|
||||
randomizer_t *randomizer = randomizer_create();
|
||||
|
||||
/* generate a random nonce */
|
||||
randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce);
|
||||
randomizer->destroy(randomizer);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||
ASN1_nonce_oid,
|
||||
asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
|
||||
}
|
||||
|
||||
/**
|
||||
* build requestExtensions (into TBSRequest)
|
||||
*/
|
||||
static chunk_t build_request_ext(private_ocsp_t *this)
|
||||
{
|
||||
return asn1_wrap(ASN1_CONTEXT_C_2, "m",
|
||||
asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
build_nonce_extension(this),
|
||||
asn1_wrap(ASN1_SEQUENCE, "cc",
|
||||
ASN1_response_oid,
|
||||
ASN1_response_content
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* build TBSRequest (into OCSPRequest)
|
||||
*/
|
||||
static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert)
|
||||
{
|
||||
/* version is skipped since the default is ok */
|
||||
return asn1_wrap(ASN1_SEQUENCE, "mmm",
|
||||
(has_requestor_cert)? build_requestor_name(this): chunk_empty,
|
||||
build_request_list(this),
|
||||
build_request_ext(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* build signature into ocsp request
|
||||
* gets built only if a request cert with a corresponding private key is found
|
||||
*/
|
||||
static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest)
|
||||
{
|
||||
/* TODO */
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce
|
||||
*/
|
||||
static chunk_t ocsp_build_request(private_ocsp_t *this)
|
||||
{
|
||||
bool has_requestor_cert;
|
||||
chunk_t keyid = this->cacert->get_keyid(this->cacert);
|
||||
chunk_t tbsRequest, signature;
|
||||
|
||||
DBG2("assembling ocsp request");
|
||||
DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert));
|
||||
DBG2("keyid: %#B", &keyid);
|
||||
|
||||
/* looks for requestor cert and matching private key */
|
||||
has_requestor_cert = FALSE;
|
||||
|
||||
/* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */
|
||||
|
||||
/* build content */
|
||||
tbsRequest = build_tbs_request(this, has_requestor_cert);
|
||||
|
||||
/* sign tbsReuqest */
|
||||
signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty;
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
tbsRequest,
|
||||
signature);
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a basic OCSP response
|
||||
*/
|
||||
static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res)
|
||||
{
|
||||
u_int level, version;
|
||||
asn1_ctx_t ctx;
|
||||
bool critical;
|
||||
chunk_t object;
|
||||
int objectID = 0;
|
||||
int extn_oid = OID_UNKNOWN;
|
||||
|
||||
asn1_init(&ctx, blob, level0, FALSE, FALSE);
|
||||
|
||||
while (objectID < BASIC_RESPONSE_ROOF)
|
||||
{
|
||||
if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case BASIC_RESPONSE_TBS_DATA:
|
||||
res->tbs = object;
|
||||
break;
|
||||
case BASIC_RESPONSE_VERSION:
|
||||
version = (object.len)? (1 + (u_int)*object.ptr) : 1;
|
||||
if (version != OCSP_BASIC_RESPONSE_VERSION)
|
||||
{
|
||||
DBG1("wrong ocsp basic response version (version= %i)", version);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case BASIC_RESPONSE_ID_BY_NAME:
|
||||
res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object);
|
||||
DBG2(" '%D'", res->responder_id_name);
|
||||
break;
|
||||
case BASIC_RESPONSE_ID_BY_KEY:
|
||||
res->responder_id_key = object;
|
||||
break;
|
||||
case BASIC_RESPONSE_PRODUCED_AT:
|
||||
res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
|
||||
break;
|
||||
case BASIC_RESPONSE_RESPONSES:
|
||||
res->responses = object;
|
||||
break;
|
||||
case BASIC_RESPONSE_EXT_ID:
|
||||
extn_oid = known_oid(object);
|
||||
break;
|
||||
case BASIC_RESPONSE_CRITICAL:
|
||||
critical = object.len && *object.ptr;
|
||||
DBG2(" %s", critical? "TRUE" : "FALSE");
|
||||
break;
|
||||
case BASIC_RESPONSE_EXT_VALUE:
|
||||
if (extn_oid == OID_NONCE)
|
||||
res->nonce = object;
|
||||
break;
|
||||
case BASIC_RESPONSE_ALGORITHM:
|
||||
res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
|
||||
break;
|
||||
case BASIC_RESPONSE_SIGNATURE:
|
||||
res->signature = object;
|
||||
break;
|
||||
case BASIC_RESPONSE_CERTIFICATE:
|
||||
{
|
||||
chunk_t blob = chunk_clone(object);
|
||||
|
||||
res->responder_cert = x509_create_from_chunk(blob, level+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse an ocsp response and return the result as a response_t struct
|
||||
*/
|
||||
static response_status ocsp_parse_response(response_t *res)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
int ocspResponseType = OID_UNKNOWN;
|
||||
response_status rStatus = STATUS_INTERNALERROR;
|
||||
|
||||
asn1_init(&ctx, res->chunk, 0, FALSE, FALSE);
|
||||
|
||||
while (objectID < OCSP_RESPONSE_ROOF)
|
||||
{
|
||||
if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return STATUS_INTERNALERROR;
|
||||
}
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case OCSP_RESPONSE_STATUS:
|
||||
rStatus = (response_status) *object.ptr;
|
||||
DBG2(" '%N'", response_status_names, rStatus);
|
||||
|
||||
switch (rStatus)
|
||||
{
|
||||
case STATUS_SUCCESSFUL:
|
||||
break;
|
||||
case STATUS_MALFORMEDREQUEST:
|
||||
case STATUS_INTERNALERROR:
|
||||
case STATUS_TRYLATER:
|
||||
case STATUS_SIGREQUIRED:
|
||||
case STATUS_UNAUTHORIZED:
|
||||
DBG1("unsuccessful ocsp response: server said '%N'",
|
||||
response_status_names, rStatus);
|
||||
return rStatus;
|
||||
default:
|
||||
return STATUS_INTERNALERROR;
|
||||
}
|
||||
break;
|
||||
case OCSP_RESPONSE_TYPE:
|
||||
ocspResponseType = known_oid(object);
|
||||
break;
|
||||
case OCSP_RESPONSE:
|
||||
{
|
||||
switch (ocspResponseType)
|
||||
{
|
||||
case OID_BASIC:
|
||||
if (!ocsp_parse_basic_response(object, level+1, res))
|
||||
{
|
||||
return STATUS_INTERNALERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBG1("ocsp response is not of type BASIC");
|
||||
DBG1("ocsp response OID: %#B", &object);
|
||||
return STATUS_INTERNALERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
return rStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the OCSP response has a valid signature
|
||||
*/
|
||||
static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
|
||||
{
|
||||
rsa_public_key_t *public_key;
|
||||
time_t until = UNDEFINED_TIME;
|
||||
err_t ugh;
|
||||
hash_algorithm_t algorithm = hasher_algorithm_from_oid(res->algorithm);
|
||||
|
||||
if (algorithm == HASH_UNKNOWN)
|
||||
{
|
||||
DBG1("unknown signature algorithm");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DBG2("verifying ocsp response signature:");
|
||||
DBG2("signer: '%D'", ocsp_cert->get_subject(ocsp_cert));
|
||||
DBG2("issuer: '%D'", ocsp_cert->get_issuer(ocsp_cert));
|
||||
|
||||
ugh = ocsp_cert->is_valid(ocsp_cert, &until);
|
||||
if (ugh != NULL)
|
||||
{
|
||||
DBG1("ocsp signer certificate %s", ugh);
|
||||
return FALSE;
|
||||
}
|
||||
public_key = ocsp_cert->get_public_key(ocsp_cert);
|
||||
|
||||
return public_key->verify_emsa_pkcs1_signature(public_key, algorithm, res->tbs, res->signature) == SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a single OCSP response
|
||||
*/
|
||||
static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0)
|
||||
{
|
||||
u_int level, extn_oid;
|
||||
asn1_ctx_t ctx;
|
||||
bool critical;
|
||||
chunk_t object;
|
||||
int objectID = 0;
|
||||
|
||||
certinfo_t *certinfo = NULL;
|
||||
|
||||
asn1_init(&ctx, blob, level0, FALSE, FALSE);
|
||||
|
||||
while (objectID < SINGLE_RESPONSE_ROOF)
|
||||
{
|
||||
if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (objectID)
|
||||
{
|
||||
case SINGLE_RESPONSE_ALGORITHM:
|
||||
if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1)
|
||||
{
|
||||
DBG1("only sha-1 hash supported in ocsp single response");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case SINGLE_RESPONSE_ISSUER_NAME_HASH:
|
||||
if (!chunk_equals(object, this->authNameID))
|
||||
{
|
||||
DBG1("ocsp single response has wrong issuer name hash");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case SINGLE_RESPONSE_ISSUER_KEY_HASH:
|
||||
if (!chunk_equals(object, this->authKeyID))
|
||||
{
|
||||
DBG1("ocsp single response has wrong issuer key hash");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case SINGLE_RESPONSE_SERIAL_NUMBER:
|
||||
{
|
||||
iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
|
||||
certinfo_t *current_certinfo;
|
||||
|
||||
while (iterator->iterate(iterator, (void**)¤t_certinfo))
|
||||
{
|
||||
if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo)))
|
||||
{
|
||||
certinfo = current_certinfo;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
if (certinfo == NULL)
|
||||
{
|
||||
DBG1("unrequested serial number in ocsp single response");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_GOOD:
|
||||
certinfo->set_status(certinfo, CERT_GOOD);
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
|
||||
certinfo->set_status(certinfo, CERT_REVOKED);
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
|
||||
certinfo->set_revocationTime(certinfo,
|
||||
asn1totime(&object, ASN1_GENERALIZEDTIME));
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
|
||||
certinfo->set_revocationReason(certinfo,
|
||||
(object.len == 1) ? *object.ptr : REASON_UNSPECIFIED);
|
||||
break;
|
||||
case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
|
||||
certinfo->set_status(certinfo, CERT_UNKNOWN);
|
||||
break;
|
||||
case SINGLE_RESPONSE_THIS_UPDATE:
|
||||
certinfo->set_thisUpdate(certinfo,
|
||||
asn1totime(&object, ASN1_GENERALIZEDTIME));
|
||||
break;
|
||||
case SINGLE_RESPONSE_NEXT_UPDATE:
|
||||
certinfo->set_nextUpdate(certinfo,
|
||||
asn1totime(&object, ASN1_GENERALIZEDTIME));
|
||||
break;
|
||||
case SINGLE_RESPONSE_EXT_ID:
|
||||
extn_oid = known_oid(object);
|
||||
break;
|
||||
case SINGLE_RESPONSE_CRITICAL:
|
||||
critical = object.len && *object.ptr;
|
||||
DBG2(" %s", critical ? "TRUE" : "FALSE");
|
||||
case SINGLE_RESPONSE_EXT_VALUE:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify and process ocsp response and update the ocsp cache
|
||||
*/
|
||||
static void ocsp_process_response(private_ocsp_t *this, response_t *res, credential_store_t *credentials)
|
||||
{
|
||||
x509_t *ocsp_cert = NULL;
|
||||
|
||||
/* parse the ocsp response without looking at the single responses yet */
|
||||
response_status status = ocsp_parse_response(res);
|
||||
|
||||
if (status != STATUS_SUCCESSFUL)
|
||||
{
|
||||
DBG1("error in ocsp response");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if there was a nonce in the request */
|
||||
if (this->nonce.ptr != NULL && res->nonce.ptr == NULL)
|
||||
{
|
||||
DBG1("ocsp response contains no nonce, replay attack possible");
|
||||
}
|
||||
|
||||
/* check if the nonces are identical */
|
||||
if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce))
|
||||
{
|
||||
DBG1("invalid nonce in ocsp response");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if we received a trusted responder certificate */
|
||||
if (res->responder_cert)
|
||||
{
|
||||
if (res->responder_cert->is_ocsp_signer(res->responder_cert))
|
||||
{
|
||||
DBG2("received certificate is ocsp signer");
|
||||
if (credentials->is_trusted(credentials, "OCSP signing", res->responder_cert))
|
||||
{
|
||||
DBG1("received ocsp signer certificate is trusted");
|
||||
ocsp_cert = credentials->add_auth_certificate(credentials,
|
||||
res->responder_cert, AUTH_OCSP);
|
||||
res->responder_cert = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("received ocsp signer certificate is not trusted - rejected");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("received certificate is no ocsp signer - rejected");
|
||||
}
|
||||
}
|
||||
|
||||
/* if we didn't receive a trusted responder cert, search the credential store */
|
||||
if (ocsp_cert == NULL)
|
||||
{
|
||||
ocsp_cert = credentials->get_auth_certificate(credentials,
|
||||
AUTH_OCSP|AUTH_CA, res->responder_id_name);
|
||||
if (ocsp_cert == NULL)
|
||||
{
|
||||
DBG1("no ocsp signer certificate found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the response signature */
|
||||
if (!ocsp_valid_response(res, ocsp_cert))
|
||||
{
|
||||
DBG1("ocsp response signature is invalid");
|
||||
return;
|
||||
}
|
||||
DBG2("ocsp response signature is valid");
|
||||
|
||||
/* now parse the single responses one at a time */
|
||||
{
|
||||
u_int level;
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
int objectID = 0;
|
||||
|
||||
asn1_init(&ctx, res->responses, 0, FALSE, FALSE);
|
||||
|
||||
while (objectID < RESPONSES_ROOF)
|
||||
{
|
||||
if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (objectID == RESPONSES_SINGLE_RESPONSE)
|
||||
{
|
||||
ocsp_parse_single_response(this, object, level+1);
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ocsp_t.fetch.
|
||||
*/
|
||||
static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials)
|
||||
{
|
||||
chunk_t request;
|
||||
response_t *response = NULL;
|
||||
|
||||
if (this->uris->get_count(this->uris) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->certinfos->insert_last(this->certinfos, (void*)certinfo);
|
||||
|
||||
request = ocsp_build_request(this);
|
||||
DBG3("ocsp request: %B", &request);
|
||||
{
|
||||
iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE);
|
||||
identification_t *uri;
|
||||
|
||||
while (iterator->iterate(iterator, (void**)&uri))
|
||||
{
|
||||
fetcher_t *fetcher;
|
||||
char uri_string[BUF_LEN];
|
||||
chunk_t uri_chunk = uri->get_encoding(uri);
|
||||
chunk_t response_chunk;
|
||||
|
||||
snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
|
||||
fetcher = fetcher_create(uri_string);
|
||||
|
||||
response_chunk = fetcher->post(fetcher, "application/ocsp-request", request);
|
||||
fetcher->destroy(fetcher);
|
||||
if (response_chunk.ptr != NULL)
|
||||
{
|
||||
response = response_create_from_chunk(response_chunk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
free(request.ptr);
|
||||
|
||||
if (response == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DBG3("ocsp response: %B", &response->chunk);
|
||||
ocsp_process_response(this, response, credentials);
|
||||
response->destroy(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ocsp_t.destroy.
|
||||
*/
|
||||
static void destroy(private_ocsp_t *this)
|
||||
{
|
||||
this->certinfos->destroy(this->certinfos);
|
||||
free(this->authNameID.ptr);
|
||||
free(this->nonce.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
|
||||
{
|
||||
private_ocsp_t *this = malloc_thing(private_ocsp_t);
|
||||
|
||||
/* initialize */
|
||||
this->cacert = cacert;
|
||||
this->uris = uris;
|
||||
this->certinfos = linked_list_create();
|
||||
this->nonce = chunk_empty;
|
||||
this->authKeyID = cacert->get_subjectKeyID(cacert);
|
||||
{
|
||||
hasher_t *hasher = hasher_create(HASH_SHA1);
|
||||
identification_t *issuer = cacert->get_subject(cacert);
|
||||
|
||||
hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
|
||||
&this->authNameID);
|
||||
hasher->destroy(hasher);
|
||||
}
|
||||
|
||||
/* public functions */
|
||||
this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch;
|
||||
this->public.destroy = (void (*) (ocsp_t*))destroy;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,12 +1,4 @@
|
||||
/**
|
||||
* @file ocsp.h
|
||||
*
|
||||
* @brief Interface of ocsp_t
|
||||
*
|
||||
*/
|
||||
|
||||
/* Support of the Online Certificate Status Protocol (OCSP) Support
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
*
|
||||
@@ -22,7 +14,12 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ocsp ocsp
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef OCSP_H_
|
||||
@@ -51,39 +48,32 @@ typedef enum {
|
||||
} response_status;
|
||||
|
||||
/**
|
||||
* @brief Online Certficate Status Protocol (OCSP)
|
||||
*
|
||||
* @ingroup transforms
|
||||
* Online Certficate Status Protocol (OCSP)
|
||||
*/
|
||||
struct ocsp_t {
|
||||
|
||||
/**
|
||||
* @brief Fetches the actual certificate status via OCSP
|
||||
* Fetches the actual certificate status via OCSP
|
||||
*
|
||||
* @param uris linked list of ocsp uris
|
||||
* @param certinfo certificate status info to be updated
|
||||
* @param credentials credential store needed for trust path verification
|
||||
*/
|
||||
void (*fetch) (ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials);
|
||||
|
||||
/**
|
||||
* @brief Destroys the ocsp_t object.
|
||||
*
|
||||
* @param this ocsp object to destroy
|
||||
* Destroys the ocsp_t object.
|
||||
*/
|
||||
void (*destroy) (ocsp_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create an ocsp_t object.
|
||||
* Create an ocsp_t object.
|
||||
*
|
||||
* @param cacert ca certificate
|
||||
* @param uris linked list of ocsp uris
|
||||
* @return created ocsp_t object
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris);
|
||||
|
||||
#endif /* OCSP_H_ */
|
||||
#endif /* OCSP_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file pkcs7.c
|
||||
*
|
||||
* @brief Implementation of pkcs7_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Copyright (C) 2002-2008 Andreas Steffen
|
||||
@@ -21,7 +14,7 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -459,10 +452,18 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert)
|
||||
}
|
||||
else
|
||||
{
|
||||
hasher_t *hasher = hasher_create(algorithm);
|
||||
hasher_t *hasher;
|
||||
chunk_t hash;
|
||||
bool valid;
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, algorithm)
|
||||
if (hasher == NULL)
|
||||
{
|
||||
DBG1("hash algorithm %N not supported",
|
||||
hash_algorithm_names, algorithm);
|
||||
free(messageDigest.ptr);
|
||||
return FALSE;
|
||||
}
|
||||
hasher->allocate_hash(hasher, this->data, &hash);
|
||||
hasher->destroy(hasher);
|
||||
DBG3("hash: %B", &hash);
|
||||
@@ -873,15 +874,24 @@ bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key,
|
||||
|
||||
if (this->attributes != NULL)
|
||||
{
|
||||
if (this->data.ptr != NULL)
|
||||
if(this->data.ptr != NULL)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, alg);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
DBG1(" hash algorithm %N not support",
|
||||
hash_algorithm_names, alg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* take the current time as signingTime */
|
||||
time_t now = time(NULL);
|
||||
chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME);
|
||||
|
||||
chunk_t messageDigest, attributes;
|
||||
hasher_t *hasher = hasher_create(alg);
|
||||
|
||||
|
||||
hasher->allocate_hash(hasher, this->data, &messageDigest);
|
||||
hasher->destroy(hasher);
|
||||
this->attributes->set_attribute(this->attributes,
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file pkcs7.h
|
||||
*
|
||||
* @brief Interface of pkcs7_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Copyright (C) 2002-2008 Andreas Steffen
|
||||
@@ -21,11 +14,16 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pkcs7 pkcs7
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef _PKCS7_H
|
||||
#define _PKCS7_H
|
||||
#ifndef _PKCS7_H_
|
||||
#define _PKCS7_H_
|
||||
|
||||
typedef struct pkcs7_t pkcs7_t;
|
||||
|
||||
@@ -37,60 +35,48 @@ typedef struct pkcs7_t pkcs7_t;
|
||||
#include <utils/iterator.h>
|
||||
|
||||
/**
|
||||
* @brief PKCS#7 contentInfo object.
|
||||
*
|
||||
* @b Constructors:
|
||||
* -pkcs7_create_from_chunk()
|
||||
* -pkcs7_create_from_data()
|
||||
*
|
||||
* @ingroup crypto
|
||||
* PKCS#7 contentInfo object.
|
||||
*/
|
||||
struct pkcs7_t {
|
||||
/**
|
||||
* @brief Check if the PKCS#7 contentType is data
|
||||
* Check if the PKCS#7 contentType is data
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if the contentType is data
|
||||
*/
|
||||
bool (*is_data) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if the PKCS#7 contentType is signedData
|
||||
* Check if the PKCS#7 contentType is signedData
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if the contentType is signedData
|
||||
*/
|
||||
bool (*is_signedData) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if the PKCS#7 contentType is envelopedData
|
||||
* Check if the PKCS#7 contentType is envelopedData
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if the contentType is envelopedData
|
||||
*/
|
||||
bool (*is_envelopedData) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Parse a PKCS#7 data content.
|
||||
* Parse a PKCS#7 data content.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if parsing was successful
|
||||
*/
|
||||
bool (*parse_data) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Parse a PKCS#7 signedData content.
|
||||
* Parse a PKCS#7 signedData content.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cacert cacert used to verify the signature
|
||||
* @return TRUE if parsing was successful
|
||||
*/
|
||||
bool (*parse_signedData) (pkcs7_t *this, x509_t *cacert);
|
||||
|
||||
/**
|
||||
* @brief Parse a PKCS#7 envelopedData content.
|
||||
* Parse a PKCS#7 envelopedData content.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param serialNumber serialNumber of the request
|
||||
* @param key RSA private key used to decrypt the symmetric key
|
||||
* @return TRUE if parsing was successful
|
||||
@@ -98,112 +84,97 @@ struct pkcs7_t {
|
||||
bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, rsa_private_key_t *key);
|
||||
|
||||
/**
|
||||
* @brief Returns the parsed data object
|
||||
* Returns the parsed data object
|
||||
*
|
||||
* @param this calling object
|
||||
* @return chunk containing the data object
|
||||
*/
|
||||
chunk_t (*get_data) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Returns the a DER-encoded contentInfo object
|
||||
* Returns the a DER-encoded contentInfo object
|
||||
*
|
||||
* @param this calling object
|
||||
* @return chunk containing the contentInfo object
|
||||
*/
|
||||
chunk_t (*get_contentInfo) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator for the certificates.
|
||||
* Create an iterator for the certificates.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator for the certificates
|
||||
*/
|
||||
iterator_t *(*create_certificate_iterator) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Add a certificate.
|
||||
* Add a certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param cert certificate to be included
|
||||
*/
|
||||
void (*set_certificate) (pkcs7_t *this, x509_t *cert);
|
||||
|
||||
/**
|
||||
* @brief Add authenticated attributes.
|
||||
* Add authenticated attributes.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param attributes attributes to be included
|
||||
*/
|
||||
void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes);
|
||||
|
||||
/**
|
||||
* @brief Build a data object
|
||||
* Build a data object
|
||||
*
|
||||
* @param this PKCS#7 data to be built
|
||||
* @return TRUE if build was successful
|
||||
*/
|
||||
bool (*build_data) (pkcs7_t *this);
|
||||
|
||||
/**
|
||||
* @brief Build an envelopedData object
|
||||
* Build an envelopedData object
|
||||
*
|
||||
* @param this PKCS#7 data object to envelop
|
||||
* @param cert receivers's certificate
|
||||
* @param alg encryption algorithm
|
||||
* @return TRUE if build was successful
|
||||
*/
|
||||
bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg);
|
||||
bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert,
|
||||
encryption_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Build an signedData object
|
||||
* Build an signedData object
|
||||
*
|
||||
* @param this PKCS#7 data object to sign
|
||||
* @param key signer's RSA private key
|
||||
* @param alg digest algorithm used for signature
|
||||
* @return TRUE if build was successful
|
||||
*/
|
||||
bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg);
|
||||
bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key,
|
||||
hash_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Destroys the contentInfo object.
|
||||
*
|
||||
* @param this PKCS#7 contentInfo object to destroy
|
||||
* Destroys the contentInfo object.
|
||||
*/
|
||||
void (*destroy) (pkcs7_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read a PKCS#7 contentInfo object from a DER encoded chunk.
|
||||
* Read a PKCS#7 contentInfo object from a DER encoded chunk.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @param level ASN.1 parsing start level
|
||||
* @return created pkcs7_contentInfo object, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level);
|
||||
|
||||
/**
|
||||
* @brief Create a PKCS#7 contentInfo object
|
||||
* Create a PKCS#7 contentInfo object
|
||||
*
|
||||
* @param chunk chunk containing data
|
||||
* @return created pkcs7_contentInfo object.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
pkcs7_t *pkcs7_create_from_data(chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Read a X.509 certificate from a DER encoded file.
|
||||
* Read a X.509 certificate from a DER encoded file.
|
||||
*
|
||||
* @param filename file containing DER encoded data
|
||||
* @param label label describing kind of PKCS#7 file
|
||||
* @return created pkcs7_t object, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label);
|
||||
|
||||
|
||||
#endif /* _PKCS7_H */
|
||||
#endif /* _PKCS7_H_ @} */
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
/**
|
||||
* @file pkcs9.c
|
||||
*
|
||||
* @brief Implementation of pkcs9_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C)2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -20,7 +12,7 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <library.h>
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
/**
|
||||
* @file pkcs7.h
|
||||
*
|
||||
* @brief Interface of pkcs9_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008 Andreas Steffen
|
||||
*
|
||||
* Copyright (C) 2008 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -20,102 +12,89 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pkcs9 pkcs9
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef _PKCS9_H
|
||||
#define _PKCS9_H
|
||||
#ifndef PKCS9_H_
|
||||
#define PKCS9_H_
|
||||
|
||||
typedef struct pkcs9_t pkcs9_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief PKCS#9 .
|
||||
*
|
||||
* @b Constructors:
|
||||
* -pkcs9_create_from_chunk()
|
||||
* -pkcs9_create()
|
||||
*
|
||||
* @ingroup crypto
|
||||
* PKCS#9 attributes.
|
||||
*/
|
||||
struct pkcs9_t {
|
||||
|
||||
/**
|
||||
* @brief generate ASN.1 encoding of attribute list
|
||||
*
|
||||
* @param this PKCS#9 attribute list to be encoded
|
||||
* Generate ASN.1 encoding of attribute list
|
||||
*/
|
||||
void (*build_encoding) (pkcs9_t *this);
|
||||
|
||||
/**
|
||||
* @brief gets ASN.1 encoding of PKCS#9 attribute list
|
||||
* Gets ASN.1 encoding of PKCS#9 attribute list
|
||||
*
|
||||
* @param this calling object
|
||||
* @return ASN.1 encoded PKCSI#9 list
|
||||
*/
|
||||
chunk_t (*get_encoding) (pkcs9_t *this);
|
||||
|
||||
/**
|
||||
* @brief gets a PKCS#9 attribute
|
||||
* Gets a PKCS#9 attribute
|
||||
*
|
||||
* @param this calling object
|
||||
* @param oid OID of the attribute
|
||||
* @return ASN.1 encoded value of the attribute
|
||||
*/
|
||||
chunk_t (*get_attribute) (pkcs9_t *this, int oid);
|
||||
|
||||
/**
|
||||
* @brief adds a PKCS#9 attribute
|
||||
* Adds a PKCS#9 attribute
|
||||
*
|
||||
* @param this calling object
|
||||
* @param oid OID of the attribute
|
||||
* @param value ASN.1 encoded value of the attribute
|
||||
*/
|
||||
void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value);
|
||||
|
||||
/**
|
||||
* @brief gets a PKCS#9 messageDigest attribute
|
||||
* Gets a PKCS#9 messageDigest attribute
|
||||
*
|
||||
* @param this calling object
|
||||
* @return messageDigest
|
||||
*/
|
||||
chunk_t (*get_messageDigest) (pkcs9_t *this);
|
||||
|
||||
/**
|
||||
* @brief add a PKCS#9 messageDigest attribute
|
||||
* Add a PKCS#9 messageDigest attribute
|
||||
*
|
||||
* @param this calling object
|
||||
* @param value messageDigest
|
||||
*/
|
||||
void (*set_messageDigest) (pkcs9_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* @brief Destroys the PKCS#9 attribute list.
|
||||
*
|
||||
* @param this PKCS#9 attribute list to destroy
|
||||
* Destroys the PKCS#9 attribute list.
|
||||
*/
|
||||
void (*destroy) (pkcs9_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read a PKCS#9 attribute list from a DER encoded chunk.
|
||||
* Read a PKCS#9 attribute list from a DER encoded chunk.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @param level ASN.1 parsing start level
|
||||
* @return created pkcs9 attribute list, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level);
|
||||
|
||||
/**
|
||||
* @brief Create an empty PKCS#9 attribute list
|
||||
* Create an empty PKCS#9 attribute list
|
||||
*
|
||||
* @param chunk chunk containing data
|
||||
* @return created pkcs9 attribute list.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
pkcs9_t *pkcs9_create(void);
|
||||
|
||||
#endif /* _PKCS9_H */
|
||||
#endif /* PKCS9_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file prf_plus.c
|
||||
*
|
||||
* @brief Implementation of prf_plus_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file prf_plus.h
|
||||
*
|
||||
* @brief Interface for prf_plus.h.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup prf_plus prf_plus
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef PRF_PLUS_H_
|
||||
@@ -29,53 +29,43 @@ typedef struct prf_plus_t prf_plus_t;
|
||||
#include <crypto/prfs/prf.h>
|
||||
|
||||
/**
|
||||
* @brief Implementation of the prf+ function described in IKEv2 RFC.
|
||||
* Implementation of the prf+ function described in IKEv2 RFC.
|
||||
*
|
||||
* This class implements the prf+ algorithm. Internally it uses a pseudo random
|
||||
* function, which implements the prf_t interface.
|
||||
*
|
||||
* See IKEv2 RFC 2.13.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - prf_plus_create()
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
struct prf_plus_t {
|
||||
/**
|
||||
* @brief Get pseudo random bytes.
|
||||
* Get pseudo random bytes.
|
||||
*
|
||||
* Get the next few bytes of the prf+ output. Space
|
||||
* must be allocated by the caller.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param length number of bytes to get
|
||||
* @param[out] buffer pointer where the generated bytes will be written
|
||||
* @param length number of bytes to get
|
||||
* @param buffer pointer where the generated bytes will be written
|
||||
*/
|
||||
void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Allocate pseudo random bytes.
|
||||
* Allocate pseudo random bytes.
|
||||
*
|
||||
* Get the next few bytes of the prf+ output. This function
|
||||
* will allocate the required space.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param length number of bytes to get
|
||||
* @param[out] chunk chunk which will hold generated bytes
|
||||
* @param length number of bytes to get
|
||||
* @param chunk chunk which will hold generated bytes
|
||||
*/
|
||||
void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* @brief Destroys a prf_plus_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
* Destroys a prf_plus_t object.
|
||||
*/
|
||||
void (*destroy) (prf_plus_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a new prf_plus_t object.
|
||||
* Creates a new prf_plus_t object.
|
||||
*
|
||||
* Seed will be cloned. prf will
|
||||
* not be cloned, must be destroyed outside after
|
||||
@@ -84,9 +74,7 @@ struct prf_plus_t {
|
||||
* @param prf prf object to use
|
||||
* @param seed input seed for prf
|
||||
* @return prf_plus_t object
|
||||
*
|
||||
* @ingroup transforms
|
||||
*/
|
||||
prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed);
|
||||
|
||||
#endif /*PRF_PLUS_H_*/
|
||||
#endif /*PRF_PLUS_H_ @} */
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file prf.c
|
||||
*
|
||||
* @brief Generic constructor for all prf_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,15 +12,12 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include "prf.h"
|
||||
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/prfs/hmac_prf.h>
|
||||
#include <crypto/prfs/fips_prf.h>
|
||||
|
||||
ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
|
||||
"PRF_UNDEFINED",
|
||||
"PRF_FIPS_SHA1_160",
|
||||
@@ -42,29 +32,3 @@ ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIP
|
||||
"PRF_HMAC_SHA2_512");
|
||||
ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512);
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
prf_t *prf_create(pseudo_random_function_t pseudo_random_function)
|
||||
{
|
||||
switch (pseudo_random_function)
|
||||
{
|
||||
case PRF_HMAC_SHA1:
|
||||
return (prf_t*)hmac_prf_create(HASH_SHA1);
|
||||
case PRF_HMAC_MD5:
|
||||
return (prf_t*)hmac_prf_create(HASH_MD5);
|
||||
case PRF_HMAC_SHA2_256:
|
||||
return (prf_t*)hmac_prf_create(HASH_SHA256);
|
||||
case PRF_HMAC_SHA2_384:
|
||||
return (prf_t*)hmac_prf_create(HASH_SHA384);
|
||||
case PRF_HMAC_SHA2_512:
|
||||
return (prf_t*)hmac_prf_create(HASH_SHA512);
|
||||
case PRF_FIPS_SHA1_160:
|
||||
return (prf_t*)fips_prf_create(20, g_sha1);
|
||||
case PRF_FIPS_DES:
|
||||
case PRF_HMAC_TIGER:
|
||||
case PRF_AES128_CBC:
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file prf.h
|
||||
*
|
||||
* @brief Interface prf_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup prf prf
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef PRF_H_
|
||||
@@ -30,12 +30,10 @@ typedef struct prf_t prf_t;
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief Pseudo random function, as in IKEv2 RFC 3.3.2.
|
||||
* Pseudo random function, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* PRF algorithms not defined in IKEv2 are allocated in "private use"
|
||||
* space.
|
||||
*
|
||||
* @ingroup prfs
|
||||
*/
|
||||
enum pseudo_random_function_t {
|
||||
PRF_UNDEFINED = 1024,
|
||||
@@ -63,80 +61,53 @@ enum pseudo_random_function_t {
|
||||
extern enum_name_t *pseudo_random_function_names;
|
||||
|
||||
/**
|
||||
* @brief Generic interface for pseudo-random-functions.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - prf_create()
|
||||
* - hmac_prf_create()
|
||||
*
|
||||
* @todo Implement more prf algorithms
|
||||
*
|
||||
* @ingroup prfs
|
||||
* Generic interface for pseudo-random-functions.
|
||||
*/
|
||||
struct prf_t {
|
||||
/**
|
||||
* @brief Generates pseudo random bytes and writes them in the buffer.
|
||||
* Generates pseudo random bytes and writes them in the buffer.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param seed a chunk containing the seed for the next bytes
|
||||
* @param[out] buffer pointer where the generated bytes will be written
|
||||
* @param seed a chunk containing the seed for the next bytes
|
||||
* @param buffer pointer where the generated bytes will be written
|
||||
*/
|
||||
void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Generates pseudo random bytes and allocate space for them.
|
||||
* Generates pseudo random bytes and allocate space for them.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param seed a chunk containing the seed for the next bytes
|
||||
* @param[out] chunk chunk which will hold generated bytes
|
||||
* @param seed a chunk containing the seed for the next bytes
|
||||
* @param chunk chunk which will hold generated bytes
|
||||
*/
|
||||
void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* @brief Get the block size of this prf_t object.
|
||||
* Get the block size of this prf_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return block size in bytes
|
||||
* @return block size in bytes
|
||||
*/
|
||||
size_t (*get_block_size) (prf_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the key size of this prf_t object.
|
||||
* Get the key size of this prf_t object.
|
||||
*
|
||||
* This is a suggestion only, all implemented PRFs accept variable key
|
||||
* length.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return key size in bytes
|
||||
* @return key size in bytes
|
||||
*/
|
||||
size_t (*get_key_size) (prf_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the key for this prf_t object.
|
||||
* Set the key for this prf_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param key key to set
|
||||
* @param key key to set
|
||||
*/
|
||||
void (*set_key) (prf_t *this, chunk_t key);
|
||||
|
||||
/**
|
||||
* @brief Destroys a prf object.
|
||||
*
|
||||
* @param this calling object
|
||||
* Destroys a prf object.
|
||||
*/
|
||||
void (*destroy) (prf_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generic constructor for a prf_t oject.
|
||||
*
|
||||
* @param pseudo_random_function Algorithm to use
|
||||
* @return
|
||||
* - prf_t object
|
||||
* - NULL if prf algorithm not supported
|
||||
*
|
||||
* @ingroup prfs
|
||||
*/
|
||||
prf_t *prf_create(pseudo_random_function_t pseudo_random_function);
|
||||
|
||||
#endif /*PRF_H_*/
|
||||
#endif /*PRF_H_ @} */
|
||||
|
||||
@@ -1,722 +0,0 @@
|
||||
/**
|
||||
* @file rsa_private_key.c
|
||||
*
|
||||
* @brief Implementation of rsa_private_key_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2007-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#include <gmp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rsa_public_key.h"
|
||||
#include "rsa_private_key.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/pem.h>
|
||||
#include <utils/randomizer.h>
|
||||
|
||||
/**
|
||||
* defined in rsa_public_key.c
|
||||
*/
|
||||
extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
|
||||
extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e);
|
||||
|
||||
/**
|
||||
* Public exponent to use for key generation.
|
||||
*/
|
||||
#define PUBLIC_EXPONENT 0x10001
|
||||
|
||||
typedef struct private_rsa_private_key_t private_rsa_private_key_t;
|
||||
|
||||
/**
|
||||
* Private data of a rsa_private_key_t object.
|
||||
*/
|
||||
struct private_rsa_private_key_t {
|
||||
/**
|
||||
* Public interface for this signer.
|
||||
*/
|
||||
rsa_private_key_t public;
|
||||
|
||||
/**
|
||||
* Version of key, as encoded in PKCS#1
|
||||
*/
|
||||
u_int version;
|
||||
|
||||
/**
|
||||
* Public modulus.
|
||||
*/
|
||||
mpz_t n;
|
||||
|
||||
/**
|
||||
* Public exponent.
|
||||
*/
|
||||
mpz_t e;
|
||||
|
||||
/**
|
||||
* Private prime 1.
|
||||
*/
|
||||
mpz_t p;
|
||||
|
||||
/**
|
||||
* Private Prime 2.
|
||||
*/
|
||||
mpz_t q;
|
||||
|
||||
/**
|
||||
* Private exponent.
|
||||
*/
|
||||
mpz_t d;
|
||||
|
||||
/**
|
||||
* Private exponent 1.
|
||||
*/
|
||||
mpz_t exp1;
|
||||
|
||||
/**
|
||||
* Private exponent 2.
|
||||
*/
|
||||
mpz_t exp2;
|
||||
|
||||
/**
|
||||
* Private coefficient.
|
||||
*/
|
||||
mpz_t coeff;
|
||||
|
||||
/**
|
||||
* Keysize in bytes.
|
||||
*/
|
||||
size_t k;
|
||||
|
||||
/**
|
||||
* Keyid formed as a SHA-1 hash of a publicKeyInfo object
|
||||
*/
|
||||
chunk_t keyid;
|
||||
|
||||
/**
|
||||
* @brief Implements the RSADP algorithm specified in PKCS#1.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Implements the RSASP1 algorithm specified in PKCS#1.
|
||||
* @param this calling object
|
||||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
|
||||
};
|
||||
|
||||
/* ASN.1 definition of a PKCS#1 RSA private key */
|
||||
static const asn1Object_t privkey_objects[] = {
|
||||
{ 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
|
||||
{ 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
|
||||
{ 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
|
||||
{ 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
|
||||
{ 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
|
||||
{ 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
|
||||
{ 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
|
||||
{ 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
|
||||
{ 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
|
||||
{ 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
|
||||
{ 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
|
||||
ASN1_LOOP }, /* 10 */
|
||||
{ 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
|
||||
{ 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
|
||||
{ 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
|
||||
{ 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
|
||||
{ 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
|
||||
};
|
||||
|
||||
#define PRIV_KEY_VERSION 1
|
||||
#define PRIV_KEY_MODULUS 2
|
||||
#define PRIV_KEY_PUB_EXP 3
|
||||
#define PRIV_KEY_PRIV_EXP 4
|
||||
#define PRIV_KEY_PRIME1 5
|
||||
#define PRIV_KEY_PRIME2 6
|
||||
#define PRIV_KEY_EXP1 7
|
||||
#define PRIV_KEY_EXP2 8
|
||||
#define PRIV_KEY_COEFF 9
|
||||
#define PRIV_KEY_ROOF 16
|
||||
|
||||
/**
|
||||
* Auxiliary function overwriting private key material with
|
||||
* pseudo-random bytes before releasing it
|
||||
*/
|
||||
static void mpz_clear_randomized(mpz_t z)
|
||||
{
|
||||
size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
|
||||
u_int8_t *random_bytes = alloca(len);
|
||||
|
||||
randomizer_t *randomizer = randomizer_create();
|
||||
|
||||
randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
|
||||
|
||||
/* overwrite mpz_t with pseudo-random bytes before clearing it */
|
||||
mpz_import(z, len, 1, 1, 1, 0, random_bytes);
|
||||
mpz_clear(z);
|
||||
|
||||
randomizer->destroy(randomizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random prime number with prime_len bytes
|
||||
*/
|
||||
static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime)
|
||||
{
|
||||
randomizer_t *randomizer;
|
||||
chunk_t random_bytes;
|
||||
status_t status;
|
||||
|
||||
randomizer = randomizer_create();
|
||||
mpz_init(*prime);
|
||||
|
||||
do
|
||||
{
|
||||
DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM);
|
||||
status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
randomizer->destroy(randomizer);
|
||||
mpz_clear(*prime);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* make sure most significant bit is set */
|
||||
random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
|
||||
|
||||
/* convert chunk to mpz value */
|
||||
mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
|
||||
|
||||
/* get next prime */
|
||||
mpz_nextprime (*prime, *prime);
|
||||
|
||||
/* free the random_bytes after overwriting them with a pseudo-random sequence */
|
||||
chunk_free_randomized(&random_bytes);
|
||||
}
|
||||
/* check if it isnt too large */
|
||||
while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len);
|
||||
|
||||
randomizer->destroy(randomizer);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
|
||||
*/
|
||||
static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
|
||||
{
|
||||
mpz_t t1, t2;
|
||||
chunk_t decrypted;
|
||||
|
||||
mpz_init(t1);
|
||||
mpz_init(t2);
|
||||
|
||||
mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
|
||||
|
||||
mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
|
||||
mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
|
||||
mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
|
||||
mpz_mod(t2, t2, this->p);
|
||||
mpz_mul(t2, t2, this->coeff);
|
||||
mpz_mod(t2, t2, this->p);
|
||||
|
||||
mpz_mul(t2, t2, this->q); /* m = m2 + h q */
|
||||
mpz_add(t1, t1, t2);
|
||||
|
||||
decrypted.len = this->k;
|
||||
decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
|
||||
|
||||
mpz_clear_randomized(t1);
|
||||
mpz_clear_randomized(t2);
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key_t.pkcs1_decrypt.
|
||||
*/
|
||||
static status_t pkcs1_decrypt(private_rsa_private_key_t *this,
|
||||
chunk_t in, chunk_t *out)
|
||||
{
|
||||
status_t status = FAILED;
|
||||
chunk_t em, em_ori;
|
||||
|
||||
/* decrypt the input data */
|
||||
em = em_ori = this->rsadp(this, in);
|
||||
|
||||
/* PKCS#1 v1.5 EME encryption formatting
|
||||
* EM = 00 || 02 || PS || 00 || M
|
||||
* PS = pseudo-random nonzero octets
|
||||
*/
|
||||
|
||||
/* check for magic bytes */
|
||||
if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x02)
|
||||
{
|
||||
DBG1("incorrect padding - probably wrong RSA key");
|
||||
goto end;
|
||||
}
|
||||
em.ptr += 2;
|
||||
em.len -= 2;
|
||||
|
||||
/* the plaintext data starts after first 0x00 byte */
|
||||
while (em.len-- > 0 && *em.ptr++ != 0x00);
|
||||
|
||||
if (em.len == 0)
|
||||
{
|
||||
DBG1("no plaintext data found");
|
||||
goto end;
|
||||
}
|
||||
|
||||
*out = chunk_clone(em);
|
||||
status = SUCCESS;
|
||||
|
||||
end:
|
||||
free(em_ori.ptr);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key_t.build_emsa_pkcs1_signature.
|
||||
*/
|
||||
static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this,
|
||||
hash_algorithm_t hash_algorithm,
|
||||
chunk_t data, chunk_t *signature)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
chunk_t em, digestInfo, hash;
|
||||
int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
|
||||
|
||||
if (hash_oid == OID_UNKNOWN)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* get hasher */
|
||||
hasher = hasher_create(hash_algorithm);
|
||||
if (hasher == NULL)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* build hash */
|
||||
hasher->allocate_hash(hasher, data, &hash);
|
||||
hasher->destroy(hasher);
|
||||
|
||||
/* build DER-encoded digestInfo */
|
||||
digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||
asn1_algorithmIdentifier(hash_oid),
|
||||
asn1_simple_object(ASN1_OCTET_STRING, hash)
|
||||
);
|
||||
chunk_free(&hash);
|
||||
|
||||
/* build chunk to rsa-decrypt:
|
||||
* EM = 0x00 || 0x01 || PS || 0x00 || T.
|
||||
* PS = 0xFF padding, with length to fill em
|
||||
* T = encoded_hash
|
||||
*/
|
||||
em.len = this->k;
|
||||
em.ptr = malloc(em.len);
|
||||
|
||||
/* fill em with padding */
|
||||
memset(em.ptr, 0xFF, em.len);
|
||||
/* set magic bytes */
|
||||
*(em.ptr) = 0x00;
|
||||
*(em.ptr+1) = 0x01;
|
||||
*(em.ptr + em.len - digestInfo.len - 1) = 0x00;
|
||||
/* set DER-encoded hash */
|
||||
memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
|
||||
|
||||
/* build signature */
|
||||
*signature = this->rsasp1(this, em);
|
||||
|
||||
free(digestInfo.ptr);
|
||||
free(em.ptr);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key_t.pkcs1_write.
|
||||
*/
|
||||
static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, bool force)
|
||||
{
|
||||
bool status;
|
||||
|
||||
chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
|
||||
ASN1_INTEGER_0,
|
||||
asn1_integer_from_mpz(this->n),
|
||||
asn1_integer_from_mpz(this->e),
|
||||
asn1_integer_from_mpz(this->d),
|
||||
asn1_integer_from_mpz(this->p),
|
||||
asn1_integer_from_mpz(this->q),
|
||||
asn1_integer_from_mpz(this->exp1),
|
||||
asn1_integer_from_mpz(this->exp2),
|
||||
asn1_integer_from_mpz(this->coeff));
|
||||
|
||||
status = chunk_write(pkcs1, filename, "pkcs1", 0066, force);
|
||||
chunk_free_randomized(&pkcs1);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key_t.get_public_key.
|
||||
*/
|
||||
rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
|
||||
{
|
||||
return rsa_public_key_create(this->n, this->e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key.belongs_to.
|
||||
*/
|
||||
static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
|
||||
{
|
||||
return chunk_equals(this->keyid, public->get_keyid(public));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the loaded key if it is valid and usable
|
||||
* TODO: Log errors
|
||||
*/
|
||||
static status_t check(private_rsa_private_key_t *this)
|
||||
{
|
||||
mpz_t t, u, q1;
|
||||
status_t status = SUCCESS;
|
||||
|
||||
/* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
|
||||
* We actually require more (for security).
|
||||
*/
|
||||
if (this->k < 512 / BITS_PER_BYTE)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* we picked a max modulus size to simplify buffer allocation */
|
||||
if (this->k > 8192 / BITS_PER_BYTE)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mpz_init(t);
|
||||
mpz_init(u);
|
||||
mpz_init(q1);
|
||||
|
||||
/* check that n == p * q */
|
||||
mpz_mul(u, this->p, this->q);
|
||||
if (mpz_cmp(u, this->n) != 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
/* check that e divides neither p-1 nor q-1 */
|
||||
mpz_sub_ui(t, this->p, 1);
|
||||
mpz_mod(t, t, this->e);
|
||||
if (mpz_cmp_ui(t, 0) == 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
mpz_sub_ui(t, this->q, 1);
|
||||
mpz_mod(t, t, this->e);
|
||||
if (mpz_cmp_ui(t, 0) == 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
/* check that d is e^-1 (mod lcm(p-1, q-1)) */
|
||||
/* see PKCS#1v2, aka RFC 2437, for the "lcm" */
|
||||
mpz_sub_ui(q1, this->q, 1);
|
||||
mpz_sub_ui(u, this->p, 1);
|
||||
mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
|
||||
mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
|
||||
mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
|
||||
|
||||
mpz_mul(t, this->d, this->e);
|
||||
mpz_mod(t, t, u);
|
||||
if (mpz_cmp_ui(t, 1) != 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
/* check that exp1 is d mod (p-1) */
|
||||
mpz_sub_ui(u, this->p, 1);
|
||||
mpz_mod(t, this->d, u);
|
||||
if (mpz_cmp(t, this->exp1) != 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
/* check that exp2 is d mod (q-1) */
|
||||
mpz_sub_ui(u, this->q, 1);
|
||||
mpz_mod(t, this->d, u);
|
||||
if (mpz_cmp(t, this->exp2) != 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
/* check that coeff is (q^-1) mod p */
|
||||
mpz_mul(t, this->coeff, this->q);
|
||||
mpz_mod(t, t, this->p);
|
||||
if (mpz_cmp_ui(t, 1) != 0)
|
||||
{
|
||||
status = FAILED;
|
||||
}
|
||||
|
||||
mpz_clear_randomized(t);
|
||||
mpz_clear_randomized(u);
|
||||
mpz_clear_randomized(q1);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_private_key.destroy.
|
||||
*/
|
||||
static void destroy(private_rsa_private_key_t *this)
|
||||
{
|
||||
mpz_clear_randomized(this->n);
|
||||
mpz_clear_randomized(this->e);
|
||||
mpz_clear_randomized(this->p);
|
||||
mpz_clear_randomized(this->q);
|
||||
mpz_clear_randomized(this->d);
|
||||
mpz_clear_randomized(this->exp1);
|
||||
mpz_clear_randomized(this->exp2);
|
||||
mpz_clear_randomized(this->coeff);
|
||||
chunk_free_randomized(&this->keyid);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal generic constructor
|
||||
*/
|
||||
static private_rsa_private_key_t *rsa_private_key_create_empty(void)
|
||||
{
|
||||
private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.pkcs1_decrypt = (status_t (*) (rsa_private_key_t*,chunk_t,chunk_t*))pkcs1_decrypt;
|
||||
this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature;
|
||||
this->public.pkcs1_write = (bool (*) (rsa_private_key_t*,const char*,bool))pkcs1_write;
|
||||
this->public.get_public_key = (rsa_public_key_t* (*) (rsa_private_key_t*))get_public_key;
|
||||
this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to;
|
||||
this->public.destroy = (void (*) (rsa_private_key_t*))destroy;
|
||||
|
||||
/* private functions */
|
||||
this->rsadp = rsadp;
|
||||
this->rsasp1 = rsadp; /* same algorithm */
|
||||
|
||||
this->keyid = chunk_empty;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create(size_t key_size)
|
||||
{
|
||||
mpz_t p, q, n, e, d, exp1, exp2, coeff;
|
||||
mpz_t m, q1, t;
|
||||
private_rsa_private_key_t *this;
|
||||
size_t key_len = key_size / BITS_PER_BYTE;
|
||||
size_t prime_len = key_len / 2;
|
||||
|
||||
/* Get values of primes p and q */
|
||||
if (compute_prime(this, prime_len, &p) != SUCCESS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (compute_prime(this, prime_len, &q) != SUCCESS)
|
||||
{
|
||||
mpz_clear(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpz_init(t);
|
||||
mpz_init(n);
|
||||
mpz_init(d);
|
||||
mpz_init(exp1);
|
||||
mpz_init(exp2);
|
||||
mpz_init(coeff);
|
||||
|
||||
/* Swapping Primes so p is larger then q */
|
||||
if (mpz_cmp(p, q) < 0)
|
||||
{
|
||||
mpz_swap(p, q);
|
||||
}
|
||||
|
||||
mpz_mul(n, p, q); /* n = p*q */
|
||||
mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
|
||||
mpz_init_set(m, p); /* m = p */
|
||||
mpz_sub_ui(m, m, 1); /* m = m -1 */
|
||||
mpz_init_set(q1, q); /* q1 = q */
|
||||
mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
|
||||
mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
|
||||
mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
|
||||
mpz_divexact(m, m, t); /* m = m / t */
|
||||
mpz_gcd(t, m, e); /* t = gcd(m, e) (greatest common divisor) */
|
||||
|
||||
mpz_invert(d, e, m); /* e has an inverse mod m */
|
||||
if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
|
||||
{
|
||||
mpz_add(d, d, m);
|
||||
}
|
||||
mpz_sub_ui(t, p, 1); /* t = p-1 */
|
||||
mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
|
||||
mpz_sub_ui(t, q, 1); /* t = q-1 */
|
||||
mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
|
||||
|
||||
mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
|
||||
if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
|
||||
{
|
||||
mpz_add(coeff, coeff, p);
|
||||
}
|
||||
|
||||
mpz_clear_randomized(q1);
|
||||
mpz_clear_randomized(m);
|
||||
mpz_clear_randomized(t);
|
||||
|
||||
/* determine exact the modulus size in bits */
|
||||
key_size = mpz_sizeinbase(n, 2);
|
||||
|
||||
/* create and fill in rsa_private_key_t object */
|
||||
this = rsa_private_key_create_empty();
|
||||
this->k = (key_size + 7) / BITS_PER_BYTE;
|
||||
this->keyid = rsa_public_key_id_create(n, e);
|
||||
*(this->p) = *p;
|
||||
*(this->q) = *q;
|
||||
*(this->n) = *n;
|
||||
*(this->e) = *e;
|
||||
*(this->d) = *d;
|
||||
*(this->exp1) = *exp1;
|
||||
*(this->exp2) = *exp2;
|
||||
*(this->coeff) = *coeff;
|
||||
DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
private_rsa_private_key_t *this;
|
||||
|
||||
this = rsa_private_key_create_empty();
|
||||
|
||||
mpz_init(this->n);
|
||||
mpz_init(this->e);
|
||||
mpz_init(this->p);
|
||||
mpz_init(this->q);
|
||||
mpz_init(this->d);
|
||||
mpz_init(this->exp1);
|
||||
mpz_init(this->exp2);
|
||||
mpz_init(this->coeff);
|
||||
|
||||
asn1_init(&ctx, blob, 0, FALSE, TRUE);
|
||||
|
||||
while (objectID < PRIV_KEY_ROOF)
|
||||
{
|
||||
if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
destroy(this);
|
||||
return FALSE;
|
||||
}
|
||||
switch (objectID)
|
||||
{
|
||||
case PRIV_KEY_VERSION:
|
||||
if (object.len > 0 && *object.ptr != 0)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case PRIV_KEY_MODULUS:
|
||||
mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_PUB_EXP:
|
||||
mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_PRIV_EXP:
|
||||
mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_PRIME1:
|
||||
mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_PRIME2:
|
||||
mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_EXP1:
|
||||
mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_EXP2:
|
||||
mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PRIV_KEY_COEFF:
|
||||
mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
|
||||
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
|
||||
this->keyid = rsa_public_key_id_create(this->n, this->e);
|
||||
|
||||
if (check(this) != SUCCESS)
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &this->public;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase)
|
||||
{
|
||||
bool pgp = FALSE;
|
||||
chunk_t chunk = chunk_empty;
|
||||
rsa_private_key_t *key = NULL;
|
||||
|
||||
if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
|
||||
return NULL;
|
||||
|
||||
key = rsa_private_key_create_from_chunk(chunk);
|
||||
chunk_free_randomized(&chunk);
|
||||
return key;
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/**
|
||||
* @file rsa_private_key.h
|
||||
*
|
||||
* @brief Interface of rsa_private_key_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2007-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#ifndef RSA_PRIVATE_KEY_H_
|
||||
#define RSA_PRIVATE_KEY_H_
|
||||
|
||||
typedef struct rsa_private_key_t rsa_private_key_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
/**
|
||||
* @brief RSA private key with associated functions.
|
||||
*
|
||||
* Currently only supports signing using EMSA encoding.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - rsa_private_key_create()
|
||||
* - rsa_private_key_create_from_chunk()
|
||||
* - rsa_private_key_create_from_file()
|
||||
*
|
||||
* @see rsa_public_key_t
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
struct rsa_private_key_t {
|
||||
|
||||
/**
|
||||
* @brief Decrypt a data block based on EME-PKCS1 encoding.
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data encrypted input data
|
||||
* @param out decrypted output data
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if padding is not correct
|
||||
*/
|
||||
status_t (*pkcs1_decrypt) (rsa_private_key_t *this, chunk_t in, chunk_t *out);
|
||||
|
||||
/**
|
||||
* @brief Build a signature over a chunk using EMSA-PKCS1 encoding.
|
||||
*
|
||||
* This signature creates a hash using the specified hash algorithm, concatenates
|
||||
* it with an ASN1-OID of the hash algorithm and runs the RSASP1 function
|
||||
* on it.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param hash_algorithm hash algorithm to use for hashing
|
||||
* @param data data to sign
|
||||
* @param[out] signature allocated signature
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - INVALID_STATE, if key not set
|
||||
* - NOT_SUPPORTED, if hash algorithm not supported
|
||||
*/
|
||||
status_t (*build_emsa_pkcs1_signature) (rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature);
|
||||
|
||||
/**
|
||||
* @brief Writes an RSA private key to a file in PKCS#1 format.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param filename file to which the key should be written.
|
||||
* @param force if TRUE overwrite existing file
|
||||
* @return TRUE if successful - FALSE otherwise
|
||||
*/
|
||||
bool (*pkcs1_write) (rsa_private_key_t *this, const char *filename, bool force);
|
||||
|
||||
/**
|
||||
* @brief Create a rsa_public_key_t with the public part of the key.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return public_key
|
||||
*/
|
||||
rsa_public_key_t *(*get_public_key) (rsa_private_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if a private key belongs to a public key.
|
||||
*
|
||||
* Compares the public part of the private key with the
|
||||
* public key, return TRUE if it equals.
|
||||
*
|
||||
* @param this private key
|
||||
* @param public public key
|
||||
* @return TRUE, if keys belong together
|
||||
*/
|
||||
bool (*belongs_to) (rsa_private_key_t *this, rsa_public_key_t *public);
|
||||
|
||||
/**
|
||||
* @brief Destroys the private key.
|
||||
*
|
||||
* @param this private key to destroy
|
||||
*/
|
||||
void (*destroy) (rsa_private_key_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generate a new RSA key with specified key length.
|
||||
*
|
||||
* @param key_size size of the key in bits
|
||||
* @return generated rsa_private_key_t.
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create(size_t key_size);
|
||||
|
||||
/**
|
||||
* @brief Load an RSA private key from a chunk.
|
||||
*
|
||||
* Load a key from a chunk, encoded as described in PKCS#1
|
||||
* (ASN1 DER encoded).
|
||||
*
|
||||
* @param chunk chunk containing the DER encoded key
|
||||
* @return loaded rsa_private_key_t, or NULL
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk);
|
||||
|
||||
/**
|
||||
* @brief Load an RSA private key from a file.
|
||||
*
|
||||
* Load a key from a file, which is either in a unencrypted binary
|
||||
* format (DER), or in a (encrypted) PEM format. The supplied
|
||||
* passphrase is used to decrypt an ecrypted key.
|
||||
*
|
||||
* @param filename filename which holds the key
|
||||
* @param passphrase optional passphase for decryption, can be NULL
|
||||
* @return loaded rsa_private_key_t, or NULL
|
||||
*
|
||||
* @todo Implement PEM file loading
|
||||
* @todo Implement key decryption
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase);
|
||||
|
||||
#endif /*RSA_PRIVATE_KEY_H_*/
|
||||
@@ -1,516 +0,0 @@
|
||||
/**
|
||||
* @file rsa_public_key.c
|
||||
*
|
||||
* @brief Implementation of rsa_public_key_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2007-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#include <gmp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rsa_public_key.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <utils/randomizer.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/pem.h>
|
||||
|
||||
/* ASN.1 definition of RSApublicKey */
|
||||
static const asn1Object_t pubkeyObjects[] = {
|
||||
{ 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||||
{ 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
|
||||
{ 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
|
||||
};
|
||||
|
||||
#define PUB_KEY_RSA_PUBLIC_KEY 0
|
||||
#define PUB_KEY_MODULUS 1
|
||||
#define PUB_KEY_EXPONENT 2
|
||||
#define PUB_KEY_ROOF 3
|
||||
|
||||
/* ASN.1 definition of digestInfo */
|
||||
static const asn1Object_t digestInfoObjects[] = {
|
||||
{ 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
|
||||
{ 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
|
||||
{ 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
|
||||
};
|
||||
|
||||
#define DIGEST_INFO 0
|
||||
#define DIGEST_INFO_ALGORITHM 1
|
||||
#define DIGEST_INFO_DIGEST 2
|
||||
#define DIGEST_INFO_ROOF 3
|
||||
|
||||
typedef struct private_rsa_public_key_t private_rsa_public_key_t;
|
||||
|
||||
/**
|
||||
* Private data structure with signing context.
|
||||
*/
|
||||
struct private_rsa_public_key_t {
|
||||
/**
|
||||
* Public interface for this signer.
|
||||
*/
|
||||
rsa_public_key_t public;
|
||||
|
||||
/**
|
||||
* Public modulus.
|
||||
*/
|
||||
mpz_t n;
|
||||
|
||||
/**
|
||||
* Public exponent.
|
||||
*/
|
||||
mpz_t e;
|
||||
|
||||
/**
|
||||
* Keysize in bytes.
|
||||
*/
|
||||
size_t k;
|
||||
|
||||
/**
|
||||
* Keyid formed as a SHA-1 hash of a publicKeyInfo object
|
||||
*/
|
||||
chunk_t keyid;
|
||||
|
||||
/**
|
||||
* @brief Implements the RSAEP algorithm specified in PKCS#1.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Implements the RSASVP1 algorithm specified in PKCS#1.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data data to process
|
||||
* @return processed data
|
||||
*/
|
||||
chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
|
||||
*/
|
||||
static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data)
|
||||
{
|
||||
mpz_t m, c;
|
||||
chunk_t encrypted;
|
||||
|
||||
mpz_init(c);
|
||||
mpz_init(m);
|
||||
|
||||
mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
|
||||
|
||||
mpz_powm(c, m, this->e, this->n);
|
||||
|
||||
encrypted.len = this->k;
|
||||
encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
|
||||
|
||||
mpz_clear(c);
|
||||
mpz_clear(m);
|
||||
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.eme_pkcs1_encrypt.
|
||||
*/
|
||||
static status_t pkcs1_encrypt(private_rsa_public_key_t *this,
|
||||
chunk_t in, chunk_t *out)
|
||||
{
|
||||
chunk_t em;
|
||||
u_char *pos;
|
||||
int padding = this->k - in.len - 3;
|
||||
|
||||
if (padding < 8)
|
||||
{
|
||||
DBG1("rsa padding of %d bytes is too small", padding);
|
||||
return FAILED;
|
||||
}
|
||||
em.len = this->k;
|
||||
em.ptr = pos = malloc(em.len);
|
||||
|
||||
/* add padding according to PKCS#1 7.2.1 1.+2. */
|
||||
*pos++ = 0x00;
|
||||
*pos++ = 0x02;
|
||||
|
||||
/* pad with pseudo random bytes unequal to zero */
|
||||
{
|
||||
randomizer_t *randomizer = randomizer_create();
|
||||
|
||||
/* pad with pseudo random bytes unequal to zero */
|
||||
while (padding--)
|
||||
{
|
||||
randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
|
||||
while (!*pos)
|
||||
{
|
||||
randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
randomizer->destroy(randomizer);
|
||||
}
|
||||
|
||||
/* append the padding terminator */
|
||||
*pos++ = 0x00;
|
||||
|
||||
/* now add the data */
|
||||
memcpy(pos, in.ptr, in.len);
|
||||
*out = this->rsaep(this, em);
|
||||
free(em.ptr);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
|
||||
*/
|
||||
static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this,
|
||||
hash_algorithm_t algorithm,
|
||||
chunk_t data, chunk_t signature)
|
||||
{
|
||||
chunk_t em_ori, em;
|
||||
status_t res = FAILED;
|
||||
|
||||
/* remove any preceding 0-bytes from signature */
|
||||
while (signature.len && *(signature.ptr) == 0x00)
|
||||
{
|
||||
signature.len -= 1;
|
||||
signature.ptr++;
|
||||
}
|
||||
|
||||
if (signature.len > this->k)
|
||||
{
|
||||
return INVALID_ARG;
|
||||
}
|
||||
|
||||
/* unpack signature */
|
||||
em_ori = em = this->rsavp1(this, signature);
|
||||
|
||||
/* result should look like this:
|
||||
* EM = 0x00 || 0x01 || PS || 0x00 || T.
|
||||
* PS = 0xFF padding, with length to fill em
|
||||
* T = oid || hash
|
||||
*/
|
||||
|
||||
/* check magic bytes */
|
||||
if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
|
||||
{
|
||||
DBG2("incorrect padding - probably wrong RSA key");
|
||||
goto end;
|
||||
}
|
||||
em.ptr += 2;
|
||||
em.len -= 2;
|
||||
|
||||
/* find magic 0x00 */
|
||||
while (em.len > 0)
|
||||
{
|
||||
if (*em.ptr == 0x00)
|
||||
{
|
||||
/* found magic byte, stop */
|
||||
em.ptr++;
|
||||
em.len--;
|
||||
break;
|
||||
}
|
||||
else if (*em.ptr != 0xFF)
|
||||
{
|
||||
/* bad padding, decryption failed ?!*/
|
||||
goto end;
|
||||
}
|
||||
em.ptr++;
|
||||
em.len--;
|
||||
}
|
||||
|
||||
if (em.len == 0)
|
||||
{
|
||||
/* no digestInfo found */
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* parse ASN.1-based digestInfo */
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
|
||||
|
||||
asn1_init(&ctx, em, 0, FALSE, FALSE);
|
||||
|
||||
while (objectID < DIGEST_INFO_ROOF)
|
||||
{
|
||||
if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
switch (objectID)
|
||||
{
|
||||
case DIGEST_INFO:
|
||||
if (em.len > object.len)
|
||||
{
|
||||
DBG1("digestInfo field in signature is followed by %u surplus bytes",
|
||||
em.len - object.len);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case DIGEST_INFO_ALGORITHM:
|
||||
{
|
||||
int hash_oid = parse_algorithmIdentifier(object, level+1, NULL);
|
||||
|
||||
hash_algorithm = hasher_algorithm_from_oid(hash_oid);
|
||||
if (hash_algorithm == HASH_UNKNOWN
|
||||
|| (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
|
||||
{
|
||||
DBG1("wrong hash algorithm used in signature");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DIGEST_INFO_DIGEST:
|
||||
{
|
||||
chunk_t hash;
|
||||
hasher_t *hasher = hasher_create(hash_algorithm);
|
||||
|
||||
if (object.len != hasher->get_hash_size(hasher))
|
||||
{
|
||||
DBG1("hash size in signature is %u bytes instead of %u bytes",
|
||||
object.len, hasher->get_hash_size(hasher));
|
||||
hasher->destroy(hasher);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* build our own hash */
|
||||
hasher->allocate_hash(hasher, data, &hash);
|
||||
hasher->destroy(hasher);
|
||||
|
||||
/* compare the hashes */
|
||||
res = memeq(object.ptr, hash.ptr, hash.len) ? SUCCESS : FAILED;
|
||||
free(hash.ptr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
free(em_ori.ptr);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.get_modulus.
|
||||
*/
|
||||
static mpz_t *get_modulus(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return (mpz_t*)&this->n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.get_keysize.
|
||||
*/
|
||||
static size_t get_keysize(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return this->k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a DER-encoded publicKeyInfo object from an RSA public key.
|
||||
* Also used in rsa_private_key.c.
|
||||
*/
|
||||
chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e)
|
||||
{
|
||||
chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_integer_from_mpz(n),
|
||||
asn1_integer_from_mpz(e));
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||
asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
|
||||
asn1_bitstring("m", publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object
|
||||
* Also used in rsa_private_key.c.
|
||||
*/
|
||||
chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e)
|
||||
{
|
||||
chunk_t keyid;
|
||||
chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e);
|
||||
hasher_t *hasher = hasher_create(HASH_SHA1);
|
||||
|
||||
hasher->allocate_hash(hasher, publicKeyInfo, &keyid);
|
||||
hasher->destroy(hasher);
|
||||
free(publicKeyInfo.ptr);
|
||||
|
||||
return keyid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.get_publicKeyInfo.
|
||||
*/
|
||||
static chunk_t get_publicKeyInfo(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return rsa_public_key_info_to_asn1(this->n, this->e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.get_keyid.
|
||||
*/
|
||||
static chunk_t get_keyid(const private_rsa_public_key_t *this)
|
||||
{
|
||||
return this->keyid;
|
||||
}
|
||||
|
||||
/* forward declaration used by rsa_public_key_t.clone */
|
||||
private_rsa_public_key_t *rsa_public_key_create_empty(void);
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.clone.
|
||||
*/
|
||||
static rsa_public_key_t* _clone(const private_rsa_public_key_t *this)
|
||||
{
|
||||
private_rsa_public_key_t *clone = rsa_public_key_create_empty();
|
||||
|
||||
mpz_init_set(clone->n, this->n);
|
||||
mpz_init_set(clone->e, this->e);
|
||||
clone->keyid = chunk_clone(this->keyid);
|
||||
clone->k = this->k;
|
||||
|
||||
return &clone->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of rsa_public_key_t.destroy.
|
||||
*/
|
||||
static void destroy(private_rsa_public_key_t *this)
|
||||
{
|
||||
mpz_clear(this->n);
|
||||
mpz_clear(this->e);
|
||||
free(this->keyid.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic private constructor
|
||||
*/
|
||||
private_rsa_public_key_t *rsa_public_key_create_empty(void)
|
||||
{
|
||||
private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt;
|
||||
this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
|
||||
this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus;
|
||||
this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize;
|
||||
this->public.get_publicKeyInfo = (chunk_t (*) (const rsa_public_key_t*))get_publicKeyInfo;
|
||||
this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid;
|
||||
this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone;
|
||||
this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
|
||||
|
||||
/* private functions */
|
||||
this->rsaep = rsaep;
|
||||
this->rsavp1 = rsaep; /* same algorithm */
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e)
|
||||
{
|
||||
private_rsa_public_key_t *this = rsa_public_key_create_empty();
|
||||
|
||||
mpz_init_set(this->n, n);
|
||||
mpz_init_set(this->e, e);
|
||||
|
||||
this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE;
|
||||
this->keyid = rsa_public_key_id_create(n, e);
|
||||
return &this->public;
|
||||
}
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob)
|
||||
{
|
||||
asn1_ctx_t ctx;
|
||||
chunk_t object;
|
||||
u_int level;
|
||||
int objectID = 0;
|
||||
|
||||
private_rsa_public_key_t *this = rsa_public_key_create_empty();
|
||||
|
||||
mpz_init(this->n);
|
||||
mpz_init(this->e);
|
||||
|
||||
asn1_init(&ctx, blob, 0, FALSE, FALSE);
|
||||
|
||||
while (objectID < PUB_KEY_ROOF)
|
||||
{
|
||||
if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx))
|
||||
{
|
||||
destroy(this);
|
||||
return FALSE;
|
||||
}
|
||||
switch (objectID)
|
||||
{
|
||||
case PUB_KEY_MODULUS:
|
||||
mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
case PUB_KEY_EXPONENT:
|
||||
mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
|
||||
break;
|
||||
}
|
||||
objectID++;
|
||||
}
|
||||
|
||||
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
|
||||
this->keyid = rsa_public_key_id_create(this->n, this->e);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create_from_file(char *filename)
|
||||
{
|
||||
bool pgp = FALSE;
|
||||
chunk_t chunk = chunk_empty;
|
||||
rsa_public_key_t *pubkey = NULL;
|
||||
|
||||
if (!pem_asn1_load_file(filename, NULL, "public key", &chunk, &pgp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pubkey = rsa_public_key_create_from_chunk(chunk);
|
||||
free(chunk.ptr);
|
||||
return pubkey;
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/**
|
||||
* @file rsa_public_key.h
|
||||
*
|
||||
* @brief Interface of rsa_public_key_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2007-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#ifndef RSA_PUBLIC_KEY_H_
|
||||
#define RSA_PUBLIC_KEY_H_
|
||||
|
||||
typedef struct rsa_public_key_t rsa_public_key_t;
|
||||
|
||||
#include <gmp.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
/**
|
||||
* @brief RSA public key with associated functions.
|
||||
*
|
||||
* Currently only supports signature verification using
|
||||
* the EMSA encoding (see PKCS1)
|
||||
*
|
||||
* @b Constructors:
|
||||
* - rsa_public_key_create()
|
||||
* - rsa_public_key_create_from_chunk()
|
||||
* - rsa_public_key_create_from_file()
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
struct rsa_public_key_t {
|
||||
|
||||
/**
|
||||
* @brief Encrypt a data block using EME-PKCS1 encoding.
|
||||
*
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data plaintext input data
|
||||
* @param out encrypted output data
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if data block is too large
|
||||
*/
|
||||
status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out);
|
||||
|
||||
/**
|
||||
* @brief Verify an EMSA-PKCS1 encoded signature.
|
||||
*
|
||||
* Processes the supplied signature with the RSAVP1 function,
|
||||
* selects the hash algorithm form the resultign ASN1-OID and
|
||||
* verifies the hash against the supplied data.
|
||||
*
|
||||
* @param this rsa_public_key to use
|
||||
* @param data data to sign
|
||||
# @param algorithm hash algorithm the signature is based on
|
||||
* @param signature signature to verify
|
||||
* @return
|
||||
* - SUCCESS, if signature ok
|
||||
* - INVALID_STATE, if key not set
|
||||
* - NOT_SUPPORTED, if hash algorithm not supported
|
||||
* - INVALID_ARG, if signature is not a signature
|
||||
* - FAILED if signature invalid or unable to verify
|
||||
*/
|
||||
status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this,
|
||||
hash_algorithm_t algorithm,
|
||||
chunk_t data, chunk_t signature);
|
||||
|
||||
/**
|
||||
* @brief Get the modulus of the key.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return modulus (n) of the key
|
||||
*/
|
||||
mpz_t *(*get_modulus) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the size of the modulus in bytes.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return size of the modulus (n) in bytes
|
||||
*/
|
||||
size_t (*get_keysize) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the DER encoded publicKeyInfo object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return DER encoded publicKeyInfo object
|
||||
*/
|
||||
chunk_t (*get_publicKeyInfo) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return keyid in the form of a SHA-1 hash
|
||||
*/
|
||||
chunk_t (*get_keyid) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Clone the public key.
|
||||
*
|
||||
* @param this public key to clone
|
||||
* @return clone of this
|
||||
*/
|
||||
rsa_public_key_t *(*clone) (const rsa_public_key_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the public key.
|
||||
*
|
||||
* @param this public key to destroy
|
||||
*/
|
||||
void (*destroy) (rsa_public_key_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a RSA public key from modulus and public exponent.
|
||||
*
|
||||
* @param n modulus
|
||||
* @param e public exponent
|
||||
* @return created rsa_public_key_t
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e);
|
||||
|
||||
/**
|
||||
* @brief Load an RSA public key from a chunk.
|
||||
*
|
||||
* Load a key from a chunk, encoded in the more frequently
|
||||
* used publicKeyInfo object (ASN1 DER encoded).
|
||||
*
|
||||
* @param chunk chunk containing the DER encoded key
|
||||
* @return loaded rsa_public_key_t, or NULL
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk);
|
||||
|
||||
/**
|
||||
* @brief Load an RSA public key from a file.
|
||||
*
|
||||
* Load a key from a file, which is either in binary
|
||||
* format (DER), or in PEM format.
|
||||
*
|
||||
* @param filename filename which holds the key
|
||||
* @return loaded rsa_public_key_t, or NULL
|
||||
*
|
||||
* @ingroup rsa
|
||||
*/
|
||||
rsa_public_key_t *rsa_public_key_create_from_file(char *filename);
|
||||
|
||||
#endif /*RSA_PUBLIC_KEY_H_*/
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file signer.c
|
||||
*
|
||||
* @brief Implementation of generic signer_t constructor.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,12 +12,12 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "signer.h"
|
||||
|
||||
#include <crypto/signers/hmac_signer.h>
|
||||
|
||||
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
|
||||
"UNDEFINED",
|
||||
"AUTH_HMAC_SHA1_128");
|
||||
@@ -40,26 +33,3 @@ ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_
|
||||
"AUTH_HMAC_SHA2_512_256");
|
||||
ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256);
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
signer_t *signer_create(integrity_algorithm_t integrity_algorithm)
|
||||
{
|
||||
switch(integrity_algorithm)
|
||||
{
|
||||
case AUTH_HMAC_SHA1_96:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA1, 12);
|
||||
case AUTH_HMAC_SHA1_128:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA1, 16);
|
||||
case AUTH_HMAC_MD5_96:
|
||||
return (signer_t *)hmac_signer_create(HASH_MD5, 12);
|
||||
case AUTH_HMAC_SHA2_256_128:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA256, 16);
|
||||
case AUTH_HMAC_SHA2_384_192:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA384, 24);
|
||||
case AUTH_HMAC_SHA2_512_256:
|
||||
return (signer_t *)hmac_signer_create(HASH_SHA512, 32);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file signer.h
|
||||
*
|
||||
* @brief Interface for signer_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -19,6 +12,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup signer signer
|
||||
* @{ @ingroup crypto
|
||||
*/
|
||||
|
||||
#ifndef SIGNER_H_
|
||||
@@ -30,11 +30,9 @@ typedef struct signer_t signer_t;
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief Integrity algorithm, as in IKEv2 RFC 3.3.2.
|
||||
* Integrity algorithm, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* Algorithms not specified in IKEv2 are allocated in private use space.
|
||||
*
|
||||
* @ingroup signers
|
||||
*/
|
||||
enum integrity_algorithm_t {
|
||||
AUTH_UNDEFINED = 1024,
|
||||
@@ -61,93 +59,65 @@ enum integrity_algorithm_t {
|
||||
extern enum_name_t *integrity_algorithm_names;
|
||||
|
||||
/**
|
||||
* @brief Generig interface for a symmetric signature algorithm.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - signer_create()
|
||||
* - hmac_signer_create()
|
||||
*
|
||||
* @todo Implement more integrity algorithms
|
||||
*
|
||||
* @ingroup signers
|
||||
* Generig interface for a symmetric signature algorithm.
|
||||
*/
|
||||
struct signer_t {
|
||||
/**
|
||||
* @brief Generate a signature.
|
||||
* Generate a signature.
|
||||
*
|
||||
* If buffer is NULL, data is processed and prepended to a next call until
|
||||
* buffer is a valid pointer.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data a chunk containing the data to sign
|
||||
* @param[out] buffer pointer where the signature will be written
|
||||
* @param data a chunk containing the data to sign
|
||||
* @param buffer pointer where the signature will be written
|
||||
*/
|
||||
void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Generate a signature and allocate space for it.
|
||||
* Generate a signature and allocate space for it.
|
||||
*
|
||||
* If chunk is NULL, data is processed and prepended to a next call until
|
||||
* chunk is a valid chunk pointer.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data a chunk containing the data to sign
|
||||
* @param[out] chunk chunk which will hold the allocated signature
|
||||
* @param data a chunk containing the data to sign
|
||||
* @param chunk chunk which will hold the allocated signature
|
||||
*/
|
||||
void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk);
|
||||
|
||||
/**
|
||||
* @brief Verify a signature.
|
||||
* Verify a signature.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data a chunk containing the data to verify
|
||||
* @param signature a chunk containing the signature
|
||||
* @return TRUE, if signature is valid, FALSE otherwise
|
||||
* @param data a chunk containing the data to verify
|
||||
* @param signature a chunk containing the signature
|
||||
* @return TRUE, if signature is valid, FALSE otherwise
|
||||
*/
|
||||
bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature);
|
||||
|
||||
/**
|
||||
* @brief Get the block size of this signature algorithm.
|
||||
* Get the block size of this signature algorithm.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return block size in bytes
|
||||
* @return block size in bytes
|
||||
*/
|
||||
size_t (*get_block_size) (signer_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the key size of the signature algorithm.
|
||||
* Get the key size of the signature algorithm.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return key size in bytes
|
||||
* @return key size in bytes
|
||||
*/
|
||||
size_t (*get_key_size) (signer_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the key for this object.
|
||||
* Set the key for this object.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param key key to set
|
||||
* @param key key to set
|
||||
*/
|
||||
void (*set_key) (signer_t *this, chunk_t key);
|
||||
|
||||
/**
|
||||
* @brief Destroys a signer_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
* Destroys a signer_t object.
|
||||
*/
|
||||
void (*destroy) (signer_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a new signer_t object.
|
||||
*
|
||||
* @param integrity_algorithm Algorithm to use for signing and verifying.
|
||||
* @return
|
||||
* - signer_t object
|
||||
* - NULL if signer not supported
|
||||
*
|
||||
* @ingroup signers
|
||||
*/
|
||||
signer_t *signer_create(integrity_algorithm_t integrity_algorithm);
|
||||
|
||||
#endif /*SIGNER_H_*/
|
||||
#endif /*SIGNER_H_ @} */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,406 +0,0 @@
|
||||
/**
|
||||
* @file x509.h
|
||||
*
|
||||
* @brief Interface of x509_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
|
||||
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
|
||||
* Copyright (C) 2002 Mario Strasser
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Copyright (C) 2000-2008 Andreas Steffen
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* RCSID $Id$
|
||||
*/
|
||||
|
||||
#ifndef X509_H_
|
||||
#define X509_H_
|
||||
|
||||
typedef struct x509_t x509_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/rsa/rsa_private_key.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
#include <crypto/certinfo.h>
|
||||
#include <crypto/ca.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/iterator.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/* authority flags */
|
||||
|
||||
#define AUTH_NONE 0x00 /* no authorities */
|
||||
#define AUTH_CA 0x01 /* certification authority */
|
||||
#define AUTH_AA 0x02 /* authorization authority */
|
||||
#define AUTH_OCSP 0x04 /* ocsp signing authority */
|
||||
|
||||
/**
|
||||
* @brief X.509 certificate.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - x509_create()
|
||||
* - x509_create_from_chunk()
|
||||
* - x509_create_from_file()
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
struct x509_t {
|
||||
|
||||
/**
|
||||
* @brief Set trusted public key life.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param until time until public key is trusted
|
||||
*/
|
||||
void (*set_until) (x509_t *this, time_t until);
|
||||
|
||||
/**
|
||||
* @brief Get trusted public key life.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return time until public key is trusted
|
||||
*/
|
||||
time_t (*get_until) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the certificate status
|
||||
*
|
||||
* @param this calling object
|
||||
* @param status certificate status
|
||||
*/
|
||||
void (*set_status) (x509_t *this, cert_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Get the certificate status
|
||||
*
|
||||
* @param this calling object
|
||||
* @return certificate status
|
||||
*/
|
||||
cert_status_t (*get_status) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Add authority flags
|
||||
*
|
||||
* @param this calling object
|
||||
* @param flag flags to be added
|
||||
*/
|
||||
void (*add_authority_flags) (x509_t *this, u_int flags);
|
||||
|
||||
/**
|
||||
* @brief Get authority flags
|
||||
*
|
||||
* @param this calling object
|
||||
* @return authority flags
|
||||
*/
|
||||
u_int (*get_authority_flags) (x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check a specific authority flag
|
||||
*
|
||||
* @param this calling object
|
||||
* @param flag flag to be checked
|
||||
* @return TRUE if flag is present
|
||||
*/
|
||||
bool (*has_authority_flag) (x509_t *this, u_int flag);
|
||||
|
||||
/**
|
||||
* @brief Get the DER-encoded X.509 certificate body
|
||||
*
|
||||
* @param this calling object
|
||||
* @return DER-encoded X.509 certificate
|
||||
*/
|
||||
chunk_t (*get_certificate) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the RSA public key from the certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return public_key
|
||||
*/
|
||||
rsa_public_key_t *(*get_public_key) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get serial number from the certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return serialNumber
|
||||
*/
|
||||
chunk_t (*get_serialNumber) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get subjectKeyID from the certificate.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return subjectKeyID
|
||||
*/
|
||||
chunk_t (*get_subjectKeyID) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get keyid from the certificate's public key.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return keyid
|
||||
*/
|
||||
chunk_t (*get_keyid) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the issuerDistinguishedName
|
||||
*
|
||||
* The resulting ID is always a identification_t
|
||||
* of type ID_DER_ASN1_DN.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return issuers ID
|
||||
*/
|
||||
identification_t *(*get_issuer) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the subjectDistinguishedName.
|
||||
*
|
||||
* The resulting ID is always a identification_t
|
||||
* of type ID_DER_ASN1_DN.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return subjects ID
|
||||
*/
|
||||
identification_t *(*get_subject) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set a link ca info
|
||||
*
|
||||
* @param this calling object
|
||||
* @param ca_info link to the info record of the issuing ca
|
||||
*/
|
||||
void (*set_ca_info) (x509_t *this, ca_info_t *ca_info);
|
||||
|
||||
/**
|
||||
* @brief Get the .
|
||||
*
|
||||
* The resulting ID is always a identification_t
|
||||
* of type ID_DER_ASN1_DN.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return link to the info record of the issuing ca
|
||||
* or NULL if it does not [yet] exist
|
||||
*/
|
||||
ca_info_t *(*get_ca_info) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator for the crlDistributionPoints.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator for crlDistributionPoints
|
||||
*/
|
||||
iterator_t *(*create_crluri_iterator) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Create an iterator for the ocspAccessLocations.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return iterator for ocspAccessLocations
|
||||
*/
|
||||
iterator_t *(*create_ocspuri_iterator) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if a certificate is trustworthy
|
||||
*
|
||||
* @param this calling object
|
||||
* @param signer signer's RSA public key
|
||||
*/
|
||||
bool (*verify) (const x509_t *this, const rsa_public_key_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Compare two certificates.
|
||||
*
|
||||
* Comparison is done via the certificates signature.
|
||||
*
|
||||
* @param this first cert for compare
|
||||
* @param other second cert for compare
|
||||
* @return TRUE if signature is equal
|
||||
*/
|
||||
bool (*equals) (const x509_t *this, const x509_t *that);
|
||||
|
||||
/**
|
||||
* @brief Checks if the certificate contains a subjectAltName equal to id.
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @param id id which is being compared to the subjectAltNames
|
||||
* @return TRUE if a match is found
|
||||
*/
|
||||
bool (*equals_subjectAltName) (const x509_t *this, identification_t *id);
|
||||
|
||||
/**
|
||||
* @brief Checks if the subject of the other cert is the issuer of this cert.
|
||||
*
|
||||
* @param this certificate
|
||||
* @param issuer potential issuer certificate
|
||||
* @return TRUE if issuer is found
|
||||
*/
|
||||
bool (*is_issuer) (const x509_t *this, const x509_t *issuer);
|
||||
|
||||
/**
|
||||
* @brief Checks the validity interval of the certificate
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @param until until = min(until, notAfter)
|
||||
* @return NULL if the certificate is valid
|
||||
*/
|
||||
err_t (*is_valid) (const x509_t *this, time_t *until);
|
||||
|
||||
/**
|
||||
* @brief Returns the CA basic constraints flag
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @return TRUE if the CA flag is set
|
||||
*/
|
||||
bool (*is_ca) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Returns the OCSPSigner extended key usage flag
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @return TRUE if the OCSPSigner flag is set
|
||||
*/
|
||||
bool (*is_ocsp_signer) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Checks if the certificate is self-signed (subject equals issuer)
|
||||
*
|
||||
* @param this certificate being examined
|
||||
* @return TRUE if self-signed
|
||||
*/
|
||||
bool (*is_self_signed) (const x509_t *this);
|
||||
|
||||
/**
|
||||
* @brief Log the certificate info to out.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param out stream to write to
|
||||
* @param utc TRUE for UTC times, FALSE for local time
|
||||
*/
|
||||
void (*list) (x509_t *this, FILE *out, bool utc);
|
||||
|
||||
/**
|
||||
* @brief Adds a list of subjectAltNames
|
||||
*
|
||||
* @param this calling object
|
||||
* @param subjectAltNames list of subjectAltNames to be added
|
||||
*/
|
||||
void (*add_subjectAltNames) (x509_t *this, linked_list_t *subjectAltNames);
|
||||
|
||||
/**
|
||||
* @brief Builds a DER-encoded signed X.509 certificate
|
||||
*
|
||||
* @param this calling object
|
||||
* @param alg hash algorithm used to compute the certificate digest
|
||||
* @param private_key RSA private key used to sign the certificate digest
|
||||
*/
|
||||
void (*build_encoding) (x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key);
|
||||
|
||||
/**
|
||||
* @brief Destroys the certificate.
|
||||
*
|
||||
* @param this certificate to destroy
|
||||
*/
|
||||
void (*destroy) (x509_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a X.509 certificate from its components
|
||||
*
|
||||
* @param serialNumber chunk containing the serialNumber
|
||||
* @param issuer issuer distinguished name
|
||||
* @param notBefore start date of validity
|
||||
* @param notAfter end date of validity
|
||||
* @param subject subject distinguished name
|
||||
* @param public_key public key
|
||||
*
|
||||
* @return created x509_t certificate, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
|
||||
time_t notBefore, time_t notAfter,
|
||||
identification_t *subject,
|
||||
rsa_public_key_t *public_key);
|
||||
|
||||
/**
|
||||
* @brief Read a X.509 certificate from a DER encoded blob.
|
||||
*
|
||||
* @param chunk chunk containing DER encoded data
|
||||
* @return created x509_t certificate, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
x509_t *x509_create_from_chunk(chunk_t chunk, u_int level);
|
||||
|
||||
/**
|
||||
* @brief Read a X.509 certificate from a DER encoded file.
|
||||
*
|
||||
* @param filename file containing DER encoded data
|
||||
* @param label label describing kind of certificate
|
||||
* @return created x509_t certificate, or NULL if invalid.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
x509_t *x509_create_from_file(const char *filename, const char *label);
|
||||
|
||||
/**
|
||||
* @brief Parses a DER encoded authorityKeyIdentifier
|
||||
*
|
||||
* @param blob blob containing DER encoded data
|
||||
* @param level0 indicates the current parsing level
|
||||
* @param authKeyID assigns the authorityKeyIdentifier
|
||||
* @param authKeySerialNumber assigns the authKeySerialNumber
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, chunk_t *authKeyID, chunk_t *authKeySerialNumber);
|
||||
|
||||
/**
|
||||
* @brief Parses DER encoded generalNames
|
||||
*
|
||||
* @param blob blob containing DER encoded data
|
||||
* @param level0 indicates the current parsing level
|
||||
* @param implicit implicit coding is used
|
||||
* @param list list of decoded generalNames
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
|
||||
|
||||
/**
|
||||
* @brief Builds a DER encoded list of generalNames
|
||||
*
|
||||
* @param list list of generalNames to be encoded
|
||||
* @return DER encoded list of generalNames
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
chunk_t x509_build_generalNames(linked_list_t *list);
|
||||
|
||||
/**
|
||||
* @brief Builds a DER encoded list of subjectAltNames
|
||||
*
|
||||
* @param list list of subjectAltNames to be encoded
|
||||
* @return DER encoded list of subjectAltNames
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
chunk_t x509_build_subjectAltNames(linked_list_t *list);
|
||||
|
||||
#endif /* X509_H_ */
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup database database
|
||||
* @{ @ingroup database
|
||||
*/
|
||||
|
||||
#ifndef DATABASE_H_
|
||||
#define DATABASE_H_
|
||||
|
||||
typedef enum db_type_t db_type_t;
|
||||
typedef struct database_t database_t;
|
||||
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
/**
|
||||
* Database column types
|
||||
*/
|
||||
enum db_type_t {
|
||||
/** integer type, argument is an "int" */
|
||||
DB_INT,
|
||||
/** unsigned integer, argument is an "u_int" */
|
||||
DB_UINT,
|
||||
/** string type, argument is a "char*" */
|
||||
DB_TEXT,
|
||||
/** binary large object type, argument is a "chunk_t" */
|
||||
DB_BLOB,
|
||||
/** floating point, argument is a "double" */
|
||||
DB_DOUBLE,
|
||||
/** NULL, takes no argument */
|
||||
DB_NULL,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a database implementation.
|
||||
*
|
||||
* @code
|
||||
int affected, rowid, aint;
|
||||
char *atext;
|
||||
database_t *db;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
db = lib->database->create("mysql://user:pass@host/database");
|
||||
affected = db->execute(db, &rowid, "INSERT INTO table VALUES (?, ?)",
|
||||
DB_INT, 77, DB_TEXT, "a text");
|
||||
printf("inserted %d row, new row ID: %d\n", affected, rowid);
|
||||
|
||||
enumerator = db->query(db, "SELECT aint, atext FROM table WHERE aint > ?",
|
||||
DB_INT, 10, // 1 argument to SQL string
|
||||
DB_INT, DB_TEXT); // 2 enumerated types in query
|
||||
if (enumerator)
|
||||
{
|
||||
while (enumerator->enumerate(enumerator, &aint, &atext))
|
||||
{
|
||||
printf("%d: %s\n", aint, atext);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
struct database_t {
|
||||
|
||||
/**
|
||||
* Run a query which returns rows, such as a SELECT.
|
||||
*
|
||||
* @param sql sql query string, containing '?' placeholders
|
||||
* @param ... list of sql placeholder db_type_t followed by its value,
|
||||
* followed by enumerators arguments as db_type_t's
|
||||
* @return enumerator as defined with arguments, NULL on failure
|
||||
*/
|
||||
enumerator_t* (*query)(database_t *this, char *sql, ...);
|
||||
|
||||
/**
|
||||
* Execute a query which dows not return rows, such as INSERT.
|
||||
*
|
||||
* @param rowid pointer to write inserted AUTO_INCREMENT row ID, or NULL
|
||||
* @param sql sql string, containing '?' placeholders
|
||||
* @param ... list of sql placeholder db_type_t followed by its value
|
||||
* @return number of affected rows, < 0 on failure
|
||||
*/
|
||||
int (*execute)(database_t *this, int *rowid, char *sql, ...);
|
||||
|
||||
/**
|
||||
* Destroy a database connection.
|
||||
*/
|
||||
void (*destroy)(database_t *this);
|
||||
};
|
||||
|
||||
#endif /* DATABASE_H_ @}*/
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "database_factory.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/mutex.h>
|
||||
|
||||
typedef struct private_database_factory_t private_database_factory_t;
|
||||
|
||||
/**
|
||||
* private data of database_factory
|
||||
*/
|
||||
struct private_database_factory_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
database_factory_t public;
|
||||
|
||||
/**
|
||||
* list of registered database_t implementations
|
||||
*/
|
||||
linked_list_t *databases;
|
||||
|
||||
/**
|
||||
* mutex to lock access to databases
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of database_factory_t.create.
|
||||
*/
|
||||
static database_t* create(private_database_factory_t *this, char *uri)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
database_t *database = NULL;
|
||||
database_constructor_t create;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
enumerator = this->databases->create_enumerator(this->databases);
|
||||
while (enumerator->enumerate(enumerator, &create))
|
||||
{
|
||||
database = create(uri);
|
||||
if (database)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_factory_t.add_database.
|
||||
*/
|
||||
static void add_database(private_database_factory_t *this,
|
||||
database_constructor_t create)
|
||||
{
|
||||
this->mutex->lock(this->mutex);
|
||||
this->databases->insert_last(this->databases, create);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_factory_t.remove_database.
|
||||
*/
|
||||
static void remove_database(private_database_factory_t *this,
|
||||
database_constructor_t create)
|
||||
{
|
||||
this->mutex->lock(this->mutex);
|
||||
this->databases->remove(this->databases, create, NULL);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of database_factory_t.destroy
|
||||
*/
|
||||
static void destroy(private_database_factory_t *this)
|
||||
{
|
||||
this->databases->destroy(this->databases);
|
||||
this->mutex->destroy(this->mutex);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
database_factory_t *database_factory_create()
|
||||
{
|
||||
private_database_factory_t *this = malloc_thing(private_database_factory_t);
|
||||
|
||||
this->public.create = (database_t*(*)(database_factory_t*, char *url))create;
|
||||
this->public.add_database = (void(*)(database_factory_t*, database_constructor_t))add_database;
|
||||
this->public.remove_database = (void(*)(database_factory_t*, database_constructor_t))remove_database;
|
||||
this->public.destroy = (void(*)(database_factory_t*))destroy;
|
||||
|
||||
this->databases = linked_list_create();
|
||||
this->mutex = mutex_create(MUTEX_DEFAULT);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup database_factory database_factory
|
||||
* @{ @ingroup database
|
||||
*/
|
||||
|
||||
#ifndef DATABASE_FACTORY_H_
|
||||
#define DATABASE_FACTORY_H_
|
||||
|
||||
typedef struct database_factory_t database_factory_t;
|
||||
|
||||
#include <database/database.h>
|
||||
|
||||
/**
|
||||
* Generic database construction function.
|
||||
*
|
||||
* @param uri implementation specific connection URI
|
||||
*/
|
||||
typedef database_t*(*database_constructor_t)(char *uri);
|
||||
|
||||
/**
|
||||
* Create instances of database connections using registered constructors.
|
||||
*/
|
||||
struct database_factory_t {
|
||||
|
||||
/**
|
||||
* Create a database connection instance.
|
||||
*
|
||||
* @param uri implementation specific connection URI
|
||||
* @return database_t instance, NULL if not supported/failed
|
||||
*/
|
||||
database_t* (*create)(database_factory_t *this, char *uri);
|
||||
|
||||
/**
|
||||
* Register a database constructor.
|
||||
*
|
||||
* @param create database constructor to register
|
||||
*/
|
||||
void (*add_database)(database_factory_t *this, database_constructor_t create);
|
||||
|
||||
/**
|
||||
* Unregister a previously registered database constructor.
|
||||
*
|
||||
* @param create database constructor to unregister
|
||||
*/
|
||||
void (*remove_database)(database_factory_t *this, database_constructor_t create);
|
||||
|
||||
/**
|
||||
* Destroy a database_factory instance.
|
||||
*/
|
||||
void (*destroy)(database_factory_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a database_factory instance.
|
||||
*/
|
||||
database_factory_t *database_factory_create();
|
||||
|
||||
#endif /* DATABASE_FACTORY_H_ @}*/
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file library.c
|
||||
*
|
||||
* @brief Logging functions for the library.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file log.h
|
||||
*
|
||||
* @brief Logging functions for the library.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup debug debug
|
||||
* @{ @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_H_
|
||||
@@ -60,4 +60,4 @@ extern void (*dbg) (int level, char *fmt, ...);
|
||||
/** default logging function, prints to stderr */
|
||||
void dbg_default(int level, char *fmt, ...);
|
||||
|
||||
#endif /* DEBUG_H_ */
|
||||
#endif /* DEBUG_H_ @} */
|
||||
|
||||
+22
-11
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file library.c
|
||||
*
|
||||
* @brief enum value to string conversion functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -46,7 +41,7 @@ static char *enum_name(enum_name_t *e, int val)
|
||||
/**
|
||||
* output handler in printf() for enum names
|
||||
*/
|
||||
static int print_enum(FILE *stream, const struct printf_info *info,
|
||||
static int print(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
enum_name_t *ed = *((enum_name_t**)(args[0]));
|
||||
@@ -65,9 +60,25 @@ static int print_enum(FILE *stream, const struct printf_info *info,
|
||||
}
|
||||
|
||||
/**
|
||||
* register printf() handlers
|
||||
* arginfo handler for printf() hook
|
||||
*/
|
||||
static void __attribute__ ((constructor))print_register()
|
||||
static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
|
||||
{
|
||||
register_printf_function(PRINTF_ENUM, print_enum, arginfo_ptr_int);
|
||||
if (n > 1)
|
||||
{
|
||||
argtypes[0] = PA_POINTER;
|
||||
argtypes[1] = PA_INT;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* return printf hook functions
|
||||
*/
|
||||
printf_hook_functions_t enum_get_printf_hooks()
|
||||
{
|
||||
printf_hook_functions_t hooks = {print, arginfo};
|
||||
|
||||
return hooks;
|
||||
}
|
||||
|
||||
|
||||
+34
-21
@@ -1,12 +1,5 @@
|
||||
/**
|
||||
* @file enum.h
|
||||
*
|
||||
* @brief enum value to string conversion functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Copyright (C) 2006-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -18,15 +11,24 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup enum enum
|
||||
* @{ @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
#ifndef ENUM_H_
|
||||
#define ENUM_H_
|
||||
|
||||
#include <printf_hook.h>
|
||||
|
||||
typedef struct enum_name_t enum_name_t;
|
||||
|
||||
/**
|
||||
* @brief Struct to store names for enums.
|
||||
* Struct to store names for enums.
|
||||
*
|
||||
* To print the string representation of enumeration values, the strings
|
||||
* are stored in these structures. Every enum_name contains a range
|
||||
@@ -34,14 +36,16 @@ typedef struct enum_name_t enum_name_t;
|
||||
* Use the convenience macros to define these linked ranges.
|
||||
*
|
||||
* For a single range, use:
|
||||
* ENUM(name, first, last, string1, string2, ...)
|
||||
*
|
||||
* @code
|
||||
ENUM(name, first, last, string1, string2, ...)
|
||||
@endcode
|
||||
* For multiple linked ranges, use:
|
||||
* ENUM_BEGIN(name, first, last, string1, string2, ...)
|
||||
* ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
|
||||
* ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
|
||||
* ENUM_END(name, last_from_previous)
|
||||
*
|
||||
* @code
|
||||
ENUM_BEGIN(name, first, last, string1, string2, ...)
|
||||
ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
|
||||
ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
|
||||
ENUM_END(name, last_from_previous)
|
||||
@endcode
|
||||
* The ENUM and the ENUM_END define a enum_name_t pointer with the name supplied
|
||||
* in "name".
|
||||
*
|
||||
@@ -62,7 +66,7 @@ struct enum_name_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Begin a new enum_name list.
|
||||
* Begin a new enum_name list.
|
||||
*
|
||||
* @param name name of the enum_name list
|
||||
* @param first enum value of the first enum string
|
||||
@@ -72,7 +76,7 @@ struct enum_name_t {
|
||||
#define ENUM_BEGIN(name, first, last, ...) static enum_name_t name##last = {first, last, NULL, { __VA_ARGS__ }}
|
||||
|
||||
/**
|
||||
* @brief Continue a enum name list startetd with ENUM_BEGIN.
|
||||
* Continue a enum name list startetd with ENUM_BEGIN.
|
||||
*
|
||||
* @param name name of the enum_name list
|
||||
* @param first enum value of the first enum string
|
||||
@@ -83,7 +87,7 @@ struct enum_name_t {
|
||||
#define ENUM_NEXT(name, first, last, prev, ...) static enum_name_t name##last = {first, last, &name##prev, { __VA_ARGS__ }}
|
||||
|
||||
/**
|
||||
* @brief Complete enum name list started with ENUM_BEGIN.
|
||||
* Complete enum name list started with ENUM_BEGIN.
|
||||
*
|
||||
* @param name name of the enum_name list
|
||||
* @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
|
||||
@@ -91,7 +95,7 @@ struct enum_name_t {
|
||||
#define ENUM_END(name, prev) enum_name_t *name = &name##prev;
|
||||
|
||||
/**
|
||||
* @brief Define a enum name with only one range.
|
||||
* Define a enum name with only one range.
|
||||
*
|
||||
* This is a convenience macro to use when a enum_name list contains only
|
||||
* one range, and is equal as defining ENUM_BEGIN followed by ENUM_END.
|
||||
@@ -103,4 +107,13 @@ struct enum_name_t {
|
||||
*/
|
||||
#define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
|
||||
|
||||
#endif /* ENUM_H_ */
|
||||
/**
|
||||
* Get printf hook functions for enum_names_t.
|
||||
*
|
||||
* The handler takes the arguments: enum_names_t *names, int value
|
||||
*
|
||||
* @return printf hook functions
|
||||
*/
|
||||
printf_hook_functions_t enum_get_printf_hooks();
|
||||
|
||||
#endif /* ENUM_H_ @}*/
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup fetcher fetcher
|
||||
* @{ @ingroup fetcher
|
||||
*/
|
||||
|
||||
#ifndef FETCHER_H_
|
||||
#define FETCHER_H_
|
||||
|
||||
typedef struct fetcher_t fetcher_t;
|
||||
typedef enum fetcher_option_t fetcher_option_t;
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Fetching options to use for fetcher_t.fetch() call.
|
||||
*/
|
||||
enum fetcher_option_t {
|
||||
|
||||
/**
|
||||
* Data to include in fetch request, e.g. on a HTTP post.
|
||||
* Additional argument is a chunk_t
|
||||
*/
|
||||
FETCH_REQUEST_DATA,
|
||||
|
||||
/**
|
||||
* Mime-Type of data included in FETCH_REQUEST_DATA.
|
||||
* Additional argument is a char*.
|
||||
*/
|
||||
FETCH_REQUEST_TYPE,
|
||||
|
||||
/**
|
||||
* Timeout to use for fetch, in seconds.
|
||||
* Additional argument is u_int
|
||||
*/
|
||||
FETCH_TIMEOUT,
|
||||
|
||||
/**
|
||||
* end of fetching options
|
||||
*/
|
||||
FETCH_END,
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor function which creates fetcher instances.
|
||||
*
|
||||
* @return fetcher instance
|
||||
*/
|
||||
typedef fetcher_t* (*fetcher_constructor_t)();
|
||||
|
||||
/**
|
||||
* Fetcher interface, an implementation fetches data from an URL.
|
||||
*/
|
||||
struct fetcher_t {
|
||||
|
||||
/**
|
||||
* Fetch data from URI into chunk.
|
||||
*
|
||||
* The fetcher returns NOT_SUPPORTED to indicate that it is uncappable
|
||||
* to handle such URLs. Other return values indicate a failure, and
|
||||
* fetching of that URL gets cancelled.
|
||||
*
|
||||
* @param uri URI to fetch from
|
||||
* @param result chunk which receives allocated data
|
||||
* @return
|
||||
* - SUCCESS if fetch was successful
|
||||
* - NOT_SUPPORTED if fetcher does not support such URLs
|
||||
* - FAILED, NOT_FOUND, PARSE_ERROR on failure
|
||||
*/
|
||||
status_t (*fetch)(fetcher_t *this, char *uri, chunk_t *result);
|
||||
|
||||
/**
|
||||
* Set a fetcher option, as defined in fetcher_option_t.
|
||||
*
|
||||
* Arguments passed to options must stay in memory until fetch() returns.
|
||||
*
|
||||
* @param option option to set
|
||||
* @param ... variable argument(s) to option
|
||||
* @return TRUE if option supported, FALSE otherwise
|
||||
*/
|
||||
bool (*set_option)(fetcher_t *this, fetcher_option_t option, ...);
|
||||
|
||||
/**
|
||||
* Destroy the fetcher instance.
|
||||
*/
|
||||
void (*destroy)(fetcher_t *this);
|
||||
};
|
||||
|
||||
#endif /* FETCHER_H_ @}*/
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "fetcher_manager.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/mutex.h>
|
||||
|
||||
typedef struct private_fetcher_manager_t private_fetcher_manager_t;
|
||||
|
||||
/**
|
||||
* private data of fetcher_manager
|
||||
*/
|
||||
struct private_fetcher_manager_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
fetcher_manager_t public;
|
||||
|
||||
/**
|
||||
* list of registered fetchers, as entry_t
|
||||
*/
|
||||
linked_list_t *fetchers;
|
||||
|
||||
/**
|
||||
* read write lock to list
|
||||
*/
|
||||
pthread_rwlock_t lock;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/** assocaited fetcher construction function */
|
||||
fetcher_constructor_t create;
|
||||
/** URL this fetcher support */
|
||||
char *url;
|
||||
} entry_t;
|
||||
|
||||
/**
|
||||
* destroy an entry_t
|
||||
*/
|
||||
static void entry_destroy(entry_t *entry)
|
||||
{
|
||||
free(entry->url);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of fetcher_manager_t.fetch.
|
||||
*/
|
||||
static status_t fetch(private_fetcher_manager_t *this,
|
||||
char *url, chunk_t *response, ...)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
status_t status = NOT_SUPPORTED;
|
||||
entry_t *entry;
|
||||
bool capable = FALSE;
|
||||
|
||||
pthread_rwlock_rdlock(&this->lock);
|
||||
enumerator = this->fetchers->create_enumerator(this->fetchers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
fetcher_option_t opt;
|
||||
fetcher_t *fetcher;
|
||||
bool good = TRUE;
|
||||
va_list args;
|
||||
|
||||
/* check URL support of fetcher */
|
||||
if (strncasecmp(entry->url, url, strlen(entry->url)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* create fetcher instance and set options */
|
||||
fetcher = entry->create();
|
||||
if (!fetcher)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
va_start(args, response);
|
||||
while (good)
|
||||
{
|
||||
opt = va_arg(args, fetcher_option_t);
|
||||
switch (opt)
|
||||
{
|
||||
case FETCH_REQUEST_DATA:
|
||||
good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
|
||||
continue;
|
||||
case FETCH_REQUEST_TYPE:
|
||||
good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
|
||||
continue;
|
||||
case FETCH_TIMEOUT:
|
||||
good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
|
||||
continue;
|
||||
case FETCH_END:
|
||||
break;;
|
||||
}
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
if (!good)
|
||||
{ /* fetcher does not support supplied options, try another */
|
||||
fetcher->destroy(fetcher);
|
||||
continue;
|
||||
}
|
||||
|
||||
status = fetcher->fetch(fetcher, url, response);
|
||||
fetcher->destroy(fetcher);
|
||||
/* try another fetcher only if this one does not support that URL */
|
||||
if (status == NOT_SUPPORTED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
capable = TRUE;
|
||||
break;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
pthread_rwlock_unlock(&this->lock);
|
||||
if (!capable)
|
||||
{
|
||||
DBG1("unable to fetch from %s, no capable fetcher found", url);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of fetcher_manager_t.add_fetcher.
|
||||
*/
|
||||
static void add_fetcher(private_fetcher_manager_t *this,
|
||||
fetcher_constructor_t create, char *url)
|
||||
{
|
||||
entry_t *entry = malloc_thing(entry_t);
|
||||
|
||||
entry->url = strdup(url);
|
||||
entry->create = create;
|
||||
|
||||
pthread_rwlock_wrlock(&this->lock);
|
||||
this->fetchers->insert_last(this->fetchers, entry);
|
||||
pthread_rwlock_unlock(&this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of fetcher_manager_t.remove_fetcher.
|
||||
*/
|
||||
static void remove_fetcher(private_fetcher_manager_t *this,
|
||||
fetcher_constructor_t create)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
|
||||
pthread_rwlock_wrlock(&this->lock);
|
||||
enumerator = this->fetchers->create_enumerator(this->fetchers);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->create == create)
|
||||
{
|
||||
this->fetchers->remove_at(this->fetchers, enumerator);
|
||||
entry_destroy(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
pthread_rwlock_unlock(&this->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of fetcher_manager_t.destroy
|
||||
*/
|
||||
static void destroy(private_fetcher_manager_t *this)
|
||||
{
|
||||
this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
|
||||
pthread_rwlock_destroy(&this->lock);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
fetcher_manager_t *fetcher_manager_create()
|
||||
{
|
||||
private_fetcher_manager_t *this = malloc_thing(private_fetcher_manager_t);
|
||||
|
||||
this->public.fetch = (status_t(*)(fetcher_manager_t*, char *url, chunk_t *response, ...))fetch;
|
||||
this->public.add_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t,char*))add_fetcher;
|
||||
this->public.remove_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t))remove_fetcher;
|
||||
this->public.destroy = (void(*)(fetcher_manager_t*))destroy;
|
||||
|
||||
this->fetchers = linked_list_create();
|
||||
pthread_rwlock_init(&this->lock, NULL);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup fetcher_manager fetcher_manager
|
||||
* @{ @ingroup fetcher
|
||||
*/
|
||||
|
||||
#ifndef FETCHER_MANAGER_H_
|
||||
#define FETCHER_MANAGER_H_
|
||||
|
||||
typedef struct fetcher_manager_t fetcher_manager_t;
|
||||
|
||||
#include <fetcher/fetcher.h>
|
||||
|
||||
/**
|
||||
* Fetches from URIs using registerd fetcher_t instances.
|
||||
*/
|
||||
struct fetcher_manager_t {
|
||||
|
||||
/**
|
||||
* Fetch data from URI into chunk.
|
||||
*
|
||||
* The variable argument list contains fetcher_option_t's, followed
|
||||
* by a option specific data argument.
|
||||
*
|
||||
* @param uri URI to fetch from
|
||||
* @param result chunk which receives allocated data
|
||||
* @param options FETCH_END terminated fetcher_option_t arguments
|
||||
* @return status indicating result of fetch
|
||||
*/
|
||||
status_t (*fetch)(fetcher_manager_t *this, char *url, chunk_t *response, ...);
|
||||
|
||||
/**
|
||||
* Register a fetcher implementation.
|
||||
*
|
||||
* @param constructor fetcher constructor function
|
||||
* @param url URL type this fetcher fetches, e.g. "http://"
|
||||
*/
|
||||
void (*add_fetcher)(fetcher_manager_t *this,
|
||||
fetcher_constructor_t constructor, char *url);
|
||||
|
||||
/**
|
||||
* Unregister a previously registered fetcher implementation.
|
||||
*
|
||||
* @param constructor fetcher constructor function to unregister
|
||||
*/
|
||||
void (*remove_fetcher)(fetcher_manager_t *this,
|
||||
fetcher_constructor_t constructor);
|
||||
|
||||
/**
|
||||
* Destroy a fetcher_manager instance.
|
||||
*/
|
||||
void (*destroy)(fetcher_manager_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a fetcher_manager instance.
|
||||
*/
|
||||
fetcher_manager_t *fetcher_manager_create();
|
||||
|
||||
#endif /* FETCHER_MANAGER_H_ @}*/
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file fips.c
|
||||
*
|
||||
* @brief Implementation of the libstrongswan integrity test.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
/**
|
||||
* @file fips.h
|
||||
*
|
||||
* @brief Interface of the libstrongswan integrity test
|
||||
*
|
||||
* @ingroup fips
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -19,6 +11,13 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup fips fips
|
||||
* @{ @ingroup fips
|
||||
*/
|
||||
|
||||
#ifndef FIPS_H_
|
||||
@@ -27,21 +26,21 @@
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* @brief compute HMAC signature over RODATA and TEXT sections of libstrongswan
|
||||
* compute HMAC signature over RODATA and TEXT sections of libstrongswan
|
||||
*
|
||||
* @param key key used for HMAC signature in ASCII string format
|
||||
* @param signature HMAC signature in HEX string format
|
||||
* @return TRUE if HMAC signature computation was successful
|
||||
* @param key key used for HMAC signature in ASCII string format
|
||||
* @param signature HMAC signature in HEX string format
|
||||
* @return TRUE if HMAC signature computation was successful
|
||||
*/
|
||||
bool fips_compute_hmac_signature(const char *key, char *signature);
|
||||
|
||||
/**
|
||||
* @brief verify HMAC signature over RODATA and TEXT sections of libstrongswan
|
||||
* verify HMAC signature over RODATA and TEXT sections of libstrongswan
|
||||
*
|
||||
* @param key key used for HMAC signature in ASCII string format
|
||||
* @param signature signature value from fips_signature.h in HEX string format
|
||||
* @return TRUE if signatures agree
|
||||
* @param key key used for HMAC signature in ASCII string format
|
||||
* @param signature signature value from fips_signature.h in HEX string format
|
||||
* @return TRUE if signatures agree
|
||||
*/
|
||||
bool fips_verify_hmac_signature(const char *key, const char *signature);
|
||||
|
||||
#endif /*FIPS_H_*/
|
||||
#endif /*FIPS_H_ @} */
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
/**
|
||||
* @file fips_canister_end.c
|
||||
*
|
||||
* @brief Marks the end of TEXT and RODATA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
|
||||
* and usage in source and binary forms are granted according to the
|
||||
* OpenSSL license.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
/**
|
||||
* @file fips_canister_start.c
|
||||
*
|
||||
* @brief Marks the start of TEXT and RODATA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
|
||||
* and usage in source and binary forms are granted according to the
|
||||
* OpenSSL license.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file fips_signer.c
|
||||
*
|
||||
* @brief Computes a HMAC signature and stores it in fips_signature.h.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 Bruno Krieg, Daniel Wydler
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
@@ -18,6 +11,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -57,7 +52,7 @@ int main(int argc, char* argv[])
|
||||
fprintf(f, "const char *hmac_key = \"%s\";\n", hmac_key);
|
||||
fprintf(f, "const char *hmac_signature = \"%s\";\n", hmac_signature);
|
||||
fprintf(f, "\n");
|
||||
fprintf(f, "#endif /* FIPS_SIGNATURE_H_ */\n");
|
||||
fprintf(f, "#endif /* FIPS_SIGNATURE_H_ @} */\n");
|
||||
fclose(f);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
+81
-165
@@ -1,13 +1,5 @@
|
||||
/**
|
||||
* @file library.c
|
||||
*
|
||||
* @brief Helper functions and definitions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -19,175 +11,99 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "library.h"
|
||||
|
||||
#include <printf_hook.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
ENUM(status_names, SUCCESS, DESTROY_ME,
|
||||
"SUCCESS",
|
||||
"FAILED",
|
||||
"OUT_OF_RES",
|
||||
"ALREADY_DONE",
|
||||
"NOT_SUPPORTED",
|
||||
"INVALID_ARG",
|
||||
"NOT_FOUND",
|
||||
"PARSE_ERROR",
|
||||
"VERIFY_ERROR",
|
||||
"INVALID_STATE",
|
||||
"DESTROY_ME",
|
||||
"NEED_MORE",
|
||||
);
|
||||
#include <utils.h>
|
||||
#include <chunk.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/host.h>
|
||||
#include <utils/leak_detective.h>
|
||||
|
||||
typedef struct private_library_t private_library_t;
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
* private data of library
|
||||
*/
|
||||
void *clalloc(void * pointer, size_t size)
|
||||
struct private_library_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
library_t public;
|
||||
|
||||
#ifdef LEAK_DETECTIVE
|
||||
/**
|
||||
* Memory leak detective, if enabled
|
||||
*/
|
||||
leak_detective_t *detective;
|
||||
#endif /* LEAK_DETECTIVE */
|
||||
};
|
||||
|
||||
/**
|
||||
* library instance
|
||||
*/
|
||||
library_t *lib;
|
||||
|
||||
/**
|
||||
* Implementation of library_t.destroy
|
||||
*/
|
||||
void library_deinit()
|
||||
{
|
||||
void *data;
|
||||
data = malloc(size);
|
||||
private_library_t *this = (private_library_t*)lib;
|
||||
|
||||
this->public.plugins->destroy(this->public.plugins);
|
||||
this->public.settings->destroy(this->public.settings);
|
||||
this->public.creds->destroy(this->public.creds);
|
||||
this->public.crypto->destroy(this->public.crypto);
|
||||
this->public.fetcher->destroy(this->public.fetcher);
|
||||
this->public.db->destroy(this->public.db);
|
||||
this->public.printf_hook->destroy(this->public.printf_hook);
|
||||
|
||||
memcpy(data, pointer,size);
|
||||
#ifdef LEAK_DETECTIVE
|
||||
if (this->detective)
|
||||
{
|
||||
this->detective->destroy(this->detective);
|
||||
}
|
||||
#endif /* LEAK_DETECTIVE */
|
||||
free(this);
|
||||
lib = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
void library_init(char *settings)
|
||||
{
|
||||
printf_hook_t *pfh;
|
||||
private_library_t *this = malloc_thing(private_library_t);
|
||||
lib = &this->public;
|
||||
|
||||
return (data);
|
||||
}
|
||||
#ifdef LEAK_DETECTIVE
|
||||
this->detective = leak_detective_create();
|
||||
#endif /* LEAK_DETECTIVE */
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
dest[i] ^= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We use a single mutex for all refcount variables. This
|
||||
* is not optimal for performance, but the critical section
|
||||
* is not that long...
|
||||
* TODO: Consider to include a mutex in each refcount_t variable.
|
||||
*/
|
||||
static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*
|
||||
* TODO: May be implemented with atomic CPU instructions
|
||||
* instead of a mutex.
|
||||
*/
|
||||
void ref_get(refcount_t *ref)
|
||||
{
|
||||
pthread_mutex_lock(&ref_mutex);
|
||||
(*ref)++;
|
||||
pthread_mutex_unlock(&ref_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*
|
||||
* TODO: May be implemented with atomic CPU instructions
|
||||
* instead of a mutex.
|
||||
*/
|
||||
bool ref_put(refcount_t *ref)
|
||||
{
|
||||
bool more_refs;
|
||||
pfh = printf_hook_create();
|
||||
this->public.printf_hook = pfh;
|
||||
|
||||
pthread_mutex_lock(&ref_mutex);
|
||||
more_refs = --(*ref);
|
||||
pthread_mutex_unlock(&ref_mutex);
|
||||
return !more_refs;
|
||||
}
|
||||
|
||||
/**
|
||||
* output handler in printf() for time_t
|
||||
*/
|
||||
static int print_time(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
static const char* months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
time_t *time = *((time_t**)(args[0]));
|
||||
bool utc = TRUE;
|
||||
struct tm t;
|
||||
pfh->add_handler(pfh, 'b', mem_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'B', chunk_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'D', identification_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'H', host_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'N', enum_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'T', time_get_printf_hooks());
|
||||
pfh->add_handler(pfh, 'V', time_delta_get_printf_hooks());
|
||||
|
||||
if (info->alt)
|
||||
{
|
||||
utc = *((bool*)(args[1]));
|
||||
}
|
||||
if (time == UNDEFINED_TIME)
|
||||
{
|
||||
return fprintf(stream, "--- -- --:--:--%s----",
|
||||
info->alt ? " UTC " : " ");
|
||||
}
|
||||
if (utc)
|
||||
{
|
||||
gmtime_r(time, &t);
|
||||
}
|
||||
else
|
||||
{
|
||||
localtime_r(time, &t);
|
||||
}
|
||||
return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d",
|
||||
months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min,
|
||||
t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
|
||||
this->public.crypto = crypto_factory_create();
|
||||
this->public.creds = credential_factory_create();
|
||||
this->public.fetcher = fetcher_manager_create();
|
||||
this->public.db = database_factory_create();
|
||||
this->public.settings = settings_create(settings);
|
||||
this->public.plugins = plugin_loader_create();
|
||||
}
|
||||
|
||||
/**
|
||||
* output handler in printf() for time deltas
|
||||
*/
|
||||
static int print_time_delta(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
char* unit = "second";
|
||||
time_t *arg1, *arg2;
|
||||
time_t delta;
|
||||
|
||||
arg1 = *((time_t**)(args[0]));
|
||||
if (info->alt)
|
||||
{
|
||||
arg2 = *((time_t**)(args[1]));
|
||||
delta = abs(*arg1 - *arg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = *arg1;
|
||||
}
|
||||
|
||||
if (delta > 2 * 60 * 60 * 24)
|
||||
{
|
||||
delta /= 60 * 60 * 24;
|
||||
unit = "day";
|
||||
}
|
||||
else if (delta > 2 * 60 * 60)
|
||||
{
|
||||
delta /= 60 * 60;
|
||||
unit = "hour";
|
||||
}
|
||||
else if (delta > 2 * 60)
|
||||
{
|
||||
delta /= 60;
|
||||
unit = "minute";
|
||||
}
|
||||
return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
|
||||
}
|
||||
|
||||
/**
|
||||
* register printf() handlers for time_t
|
||||
*/
|
||||
static void __attribute__ ((constructor))print_register()
|
||||
{
|
||||
register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
|
||||
register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr);
|
||||
}
|
||||
|
||||
+78
-284
@@ -1,12 +1,5 @@
|
||||
/**
|
||||
* @file library.h
|
||||
*
|
||||
* @brief Helper functions and definitions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -19,318 +12,119 @@
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup libstrongswan libstrongswan
|
||||
*
|
||||
* @defgroup asn1 asn1
|
||||
* @ingroup libstrongswan
|
||||
*
|
||||
* @defgroup credentials credentials
|
||||
* @ingroup libstrongswan
|
||||
*
|
||||
* @defgroup keys keys
|
||||
* @ingroup credentials
|
||||
*
|
||||
* @defgroup certificates certificates
|
||||
* @ingroup credentials
|
||||
*
|
||||
* @defgroup crypto crypto
|
||||
* @ingroup libstrongswan
|
||||
|
||||
* @defgroup database database
|
||||
* @ingroup libstrongswan
|
||||
|
||||
* @defgroup fetcher fetcher
|
||||
* @ingroup libstrongswan
|
||||
|
||||
* @defgroup fips fips
|
||||
* @ingroup libstrongswan
|
||||
|
||||
* @defgroup plugins plugins
|
||||
* @ingroup libstrongswan
|
||||
|
||||
* @defgroup utils utils
|
||||
* @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup library library
|
||||
* @{ @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
#ifndef LIBRARY_H_
|
||||
#define LIBRARY_H_
|
||||
|
||||
/**
|
||||
* @defgroup libstrongswan libstrongswan
|
||||
*
|
||||
* libstrongswan: library with various cryptographic, X.509 trust chain and
|
||||
* identity management functions.
|
||||
*/
|
||||
#include <utils.h>
|
||||
#include <chunk.h>
|
||||
#include <settings.h>
|
||||
#include <printf_hook.h>
|
||||
#include <plugins/plugin_loader.h>
|
||||
#include <crypto/crypto_factory.h>
|
||||
#include <credentials/credential_factory.h>
|
||||
#include <fetcher/fetcher_manager.h>
|
||||
#include <database/database_factory.h>
|
||||
|
||||
typedef struct library_t library_t;
|
||||
|
||||
/**
|
||||
* @defgroup asn1 asn1
|
||||
*
|
||||
* ASN.1 definitions, parser and generator functions.
|
||||
*
|
||||
* @ingroup libstrongswan
|
||||
* Libstrongswan library context, contains library relevant globals.
|
||||
*/
|
||||
struct library_t {
|
||||
|
||||
/**
|
||||
* @defgroup crypto crypto
|
||||
*
|
||||
* Various cryptographic algorithms.
|
||||
*
|
||||
* @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup crypters crypters
|
||||
*
|
||||
* Symmetric encryption algorithms, used for
|
||||
* encryption and decryption.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup hashers hashers
|
||||
*
|
||||
* Hashing algorithms, such as MD5 or SHA1
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup prfs prfs
|
||||
*
|
||||
* Pseudo random functions, used to generate
|
||||
* pseude random byte sequences.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup rsa rsa
|
||||
*
|
||||
* RSA private/public key algorithm.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup signers signers
|
||||
*
|
||||
* Symmetric signing algorithms,
|
||||
* used to ensure message integrity.
|
||||
*
|
||||
* @ingroup crypto
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup fips fips
|
||||
*
|
||||
* Code integrity check of libstrongswan
|
||||
*
|
||||
* @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup utils utils
|
||||
*
|
||||
* Generic helper classes.
|
||||
*
|
||||
* @ingroup libstrongswan
|
||||
*/
|
||||
|
||||
#include <gmp.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <printf.h>
|
||||
|
||||
#include <enum.h>
|
||||
|
||||
/**
|
||||
* Number of bits in a byte
|
||||
*/
|
||||
#define BITS_PER_BYTE 8
|
||||
|
||||
/**
|
||||
* Default length for various auxiliary text buffers
|
||||
*/
|
||||
#define BUF_LEN 512
|
||||
|
||||
/**
|
||||
* Macro compares two strings for equality
|
||||
*/
|
||||
#define streq(x,y) (strcmp(x, y) == 0)
|
||||
|
||||
/**
|
||||
* Macro compares two strings for equality
|
||||
*/
|
||||
#define strneq(x,y,len) (strncmp(x, y, len) == 0)
|
||||
|
||||
/**
|
||||
* Macro compares two binary blobs for equality
|
||||
*/
|
||||
#define memeq(x,y,len) (memcmp(x, y, len) == 0)
|
||||
|
||||
/**
|
||||
* Macro gives back larger of two values.
|
||||
*/
|
||||
#define max(x,y) ((x) > (y) ? (x):(y))
|
||||
|
||||
/**
|
||||
* Macro gives back smaller of two values.
|
||||
*/
|
||||
#define min(x,y) ((x) < (y) ? (x):(y))
|
||||
|
||||
/**
|
||||
* Call destructor of an object, if object != NULL
|
||||
*/
|
||||
#define DESTROY_IF(obj) if (obj) obj->destroy(obj)
|
||||
|
||||
/**
|
||||
* Call offset destructor of an object, if object != NULL
|
||||
*/
|
||||
#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
|
||||
|
||||
/**
|
||||
* Call function destructor of an object, if object != NULL
|
||||
*/
|
||||
#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
|
||||
|
||||
/**
|
||||
* Debug macro to follow control flow
|
||||
*/
|
||||
#define POS printf("%s, line %d\n", __FILE__, __LINE__)
|
||||
|
||||
/**
|
||||
* Macro to allocate a sized type.
|
||||
*/
|
||||
#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
|
||||
|
||||
/**
|
||||
* Assign a function as a class method
|
||||
*/
|
||||
#define ASSIGN(method, function) (method = (typeof(method))function)
|
||||
|
||||
/**
|
||||
* time_t not defined
|
||||
*/
|
||||
#define UNDEFINED_TIME 0
|
||||
|
||||
/**
|
||||
* General purpose boolean type.
|
||||
*/
|
||||
typedef int bool;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
typedef enum status_t status_t;
|
||||
|
||||
/**
|
||||
* Return values of function calls.
|
||||
*/
|
||||
enum status_t {
|
||||
/**
|
||||
* Call succeeded.
|
||||
* Printf hook registering facility
|
||||
*/
|
||||
SUCCESS,
|
||||
printf_hook_t *printf_hook;
|
||||
|
||||
/**
|
||||
* Call failed.
|
||||
* crypto algorithm registry and factory
|
||||
*/
|
||||
FAILED,
|
||||
crypto_factory_t *crypto;
|
||||
|
||||
/**
|
||||
* Out of resources.
|
||||
* credential constructor registry and factory
|
||||
*/
|
||||
OUT_OF_RES,
|
||||
credential_factory_t *creds;
|
||||
|
||||
/**
|
||||
* The suggested operation is already done
|
||||
* URL fetching facility
|
||||
*/
|
||||
ALREADY_DONE,
|
||||
fetcher_manager_t *fetcher;
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
* database construction factory
|
||||
*/
|
||||
NOT_SUPPORTED,
|
||||
database_factory_t *db;
|
||||
|
||||
/**
|
||||
* One of the arguments is invalid.
|
||||
* plugin loading facility
|
||||
*/
|
||||
INVALID_ARG,
|
||||
plugin_loader_t *plugins;
|
||||
|
||||
/**
|
||||
* Something could not be found.
|
||||
* various settings loaded from settings file
|
||||
*/
|
||||
NOT_FOUND,
|
||||
|
||||
/**
|
||||
* Error while parsing.
|
||||
*/
|
||||
PARSE_ERROR,
|
||||
|
||||
/**
|
||||
* Error while verifying.
|
||||
*/
|
||||
VERIFY_ERROR,
|
||||
|
||||
/**
|
||||
* Object in invalid state.
|
||||
*/
|
||||
INVALID_STATE,
|
||||
|
||||
/**
|
||||
* Destroy object which called method belongs to.
|
||||
*/
|
||||
DESTROY_ME,
|
||||
|
||||
/**
|
||||
* Another call to the method is required.
|
||||
*/
|
||||
NEED_MORE,
|
||||
settings_t *settings;
|
||||
};
|
||||
|
||||
/**
|
||||
* used by strict_crl_policy
|
||||
*/
|
||||
typedef enum {
|
||||
STRICT_NO,
|
||||
STRICT_YES,
|
||||
STRICT_IFURI
|
||||
} strict_t;
|
||||
|
||||
/**
|
||||
* enum_names for type status_t.
|
||||
*/
|
||||
extern enum_name_t *status_names;
|
||||
|
||||
/**
|
||||
* deprecated pluto style return value:
|
||||
* error message, NULL for success
|
||||
*/
|
||||
typedef const char *err_t;
|
||||
|
||||
/**
|
||||
* Handle struct timeval like an own type.
|
||||
*/
|
||||
typedef struct timeval timeval_t;
|
||||
|
||||
/**
|
||||
* Handle struct timespec like an own type.
|
||||
*/
|
||||
typedef struct timespec timespec_t;
|
||||
|
||||
/**
|
||||
* Handle struct chunk_t like an own type.
|
||||
*/
|
||||
typedef struct sockaddr sockaddr_t;
|
||||
|
||||
/**
|
||||
* Clone a data to a newly allocated buffer
|
||||
*/
|
||||
void *clalloc(void *pointer, size_t size);
|
||||
|
||||
/**
|
||||
* Same as memcpy, but XORs src into dst instead of copy
|
||||
*/
|
||||
void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
|
||||
|
||||
/**
|
||||
* Special type to count references
|
||||
*/
|
||||
typedef volatile u_int refcount_t;
|
||||
|
||||
/**
|
||||
* @brief Get a new reference.
|
||||
* Initialize library, creates "lib" instance.
|
||||
*
|
||||
* Increments the reference counter atomic.
|
||||
*
|
||||
* @param ref pointer to ref counter
|
||||
* @param settings file to read settings from, may be NULL for none
|
||||
*/
|
||||
void ref_get(refcount_t *ref);
|
||||
void library_init(char *settings);
|
||||
|
||||
/**
|
||||
* @brief Put back a unused reference.
|
||||
*
|
||||
* Decrements the reference counter atomic and
|
||||
* says if more references available.
|
||||
*
|
||||
* @param ref pointer to ref counter
|
||||
* @return TRUE if no more references counted
|
||||
* Deinitialize library, destroys "lib" instance.
|
||||
*/
|
||||
bool ref_put(refcount_t *ref);
|
||||
void library_deinit();
|
||||
|
||||
/**
|
||||
* Library instance, set after between library_init() and library_deinit() calls.
|
||||
*/
|
||||
extern library_t *lib;
|
||||
|
||||
#include <chunk.h>
|
||||
#include <printf_hook.h>
|
||||
|
||||
#endif /* LIBRARY_H_ */
|
||||
#endif /* LIBRARY_H_ @}*/
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-aes.la
|
||||
|
||||
libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
|
||||
libstrongswan_aes_la_LDFLAGS = -module
|
||||
|
||||
+32
-31
@@ -1,11 +1,4 @@
|
||||
/**
|
||||
* @file aes_cbc_crypter.c
|
||||
*
|
||||
* @brief Implementation of aes_cbc_crypter_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -20,11 +13,11 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "aes_cbc_crypter.h"
|
||||
|
||||
|
||||
#include "aes_crypter.h"
|
||||
|
||||
/*
|
||||
* The number of key schedule words for different block and key lengths
|
||||
@@ -43,19 +36,19 @@
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
|
||||
typedef struct private_aes_crypter_t private_aes_crypter_t;
|
||||
|
||||
/**
|
||||
* @brief Class implementing the AES symmetric encryption algorithm.
|
||||
* Class implementing the AES symmetric encryption algorithm.
|
||||
*
|
||||
* @ingroup crypters
|
||||
*/
|
||||
struct private_aes_cbc_crypter_t {
|
||||
struct private_aes_crypter_t {
|
||||
|
||||
/**
|
||||
* Public part of this class.
|
||||
*/
|
||||
aes_cbc_crypter_t public;
|
||||
aes_crypter_t public;
|
||||
|
||||
/**
|
||||
* Number of words in the key input block.
|
||||
@@ -91,7 +84,7 @@ struct private_aes_cbc_crypter_t {
|
||||
* @param[in] in_blk block to decrypt
|
||||
* @param[out] out_blk decrypted data are written to this location
|
||||
*/
|
||||
void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
void (*decrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
|
||||
/**
|
||||
* Encrypts a block.
|
||||
@@ -102,7 +95,7 @@ struct private_aes_cbc_crypter_t {
|
||||
* @param[in] in_blk block to encrypt
|
||||
* @param[out] out_blk encrypted data are written to this location
|
||||
*/
|
||||
void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
void (*encrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
|
||||
};
|
||||
|
||||
|
||||
@@ -1243,9 +1236,9 @@ switch(nc) \
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Implementation of private_aes_cbc_crypter_t.encrypt_block.
|
||||
* Implementation of private_aes_crypter_t.encrypt_block.
|
||||
*/
|
||||
static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
|
||||
static void encrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
|
||||
{ u_int32_t locals(b0, b1);
|
||||
const u_int32_t *kp = this->aes_e_key;
|
||||
|
||||
@@ -1304,9 +1297,9 @@ static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_aes_cbc_crypter_t.decrypt_block.
|
||||
* Implementation of private_aes_crypter_t.decrypt_block.
|
||||
*/
|
||||
static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
|
||||
static void decrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
|
||||
{ u_int32_t locals(b0, b1);
|
||||
const u_int32_t *kp = this->aes_d_key;
|
||||
|
||||
@@ -1367,7 +1360,7 @@ static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
|
||||
/**
|
||||
* Implementation of crypter_t.decrypt.
|
||||
*/
|
||||
static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
|
||||
static status_t decrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
|
||||
{
|
||||
int ret, pos;
|
||||
const u_int32_t *iv_i;
|
||||
@@ -1415,7 +1408,7 @@ static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
|
||||
/**
|
||||
* Implementation of crypter_t.decrypt.
|
||||
*/
|
||||
static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
|
||||
static status_t encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
|
||||
{
|
||||
int ret, pos;
|
||||
const u_int32_t *iv_i;
|
||||
@@ -1460,7 +1453,7 @@ static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
|
||||
/**
|
||||
* Implementation of crypter_t.get_block_size.
|
||||
*/
|
||||
static size_t get_block_size (private_aes_cbc_crypter_t *this)
|
||||
static size_t get_block_size (private_aes_crypter_t *this)
|
||||
{
|
||||
return AES_BLOCK_SIZE;
|
||||
}
|
||||
@@ -1468,7 +1461,7 @@ static size_t get_block_size (private_aes_cbc_crypter_t *this)
|
||||
/**
|
||||
* Implementation of crypter_t.get_key_size.
|
||||
*/
|
||||
static size_t get_key_size (private_aes_cbc_crypter_t *this)
|
||||
static size_t get_key_size (private_aes_crypter_t *this)
|
||||
{
|
||||
return this->key_size;
|
||||
}
|
||||
@@ -1476,7 +1469,7 @@ static size_t get_key_size (private_aes_cbc_crypter_t *this)
|
||||
/**
|
||||
* Implementation of crypter_t.set_key.
|
||||
*/
|
||||
static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
|
||||
static status_t set_key (private_aes_crypter_t *this, chunk_t key)
|
||||
{
|
||||
u_int32_t *kf, *kt, rci, f = 0;
|
||||
u_int8_t *in_key = key.ptr;
|
||||
@@ -1570,9 +1563,9 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of crypter_t.destroy and aes_cbc_crypter_t.destroy.
|
||||
* Implementation of crypter_t.destroy and aes_crypter_t.destroy.
|
||||
*/
|
||||
static void destroy (private_aes_cbc_crypter_t *this)
|
||||
static void destroy (private_aes_crypter_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
@@ -1580,16 +1573,24 @@ static void destroy (private_aes_cbc_crypter_t *this)
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
|
||||
aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, size_t key_size)
|
||||
{
|
||||
private_aes_cbc_crypter_t *this = malloc_thing(private_aes_cbc_crypter_t);
|
||||
private_aes_crypter_t *this;
|
||||
|
||||
if (algo != ENCR_AES_CBC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this = malloc_thing(private_aes_crypter_t);
|
||||
|
||||
#if !defined(FIXED_TABLES)
|
||||
if(!tab_gen) { gen_tabs(); tab_gen = 1; }
|
||||
#endif
|
||||
|
||||
this->key_size = key_size;
|
||||
switch(key_size) {
|
||||
switch(key_size)
|
||||
{
|
||||
case 32: /* bytes */
|
||||
this->aes_Nkey = 8;
|
||||
break;
|
||||
+17
-28
@@ -1,13 +1,5 @@
|
||||
/**
|
||||
* @file aes_cbc_crypter.h
|
||||
*
|
||||
* @brief Interface of aes_cbc_crypter_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -22,22 +14,22 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef AES_CBC_CRYPTER_H_
|
||||
#define AES_CBC_CRYPTER_H_
|
||||
/**
|
||||
* @defgroup aes_crypter aes_crypter
|
||||
* @{ @ingroup aes_p
|
||||
*/
|
||||
|
||||
typedef struct aes_cbc_crypter_t aes_cbc_crypter_t;
|
||||
#ifndef AES_CRYPTER_H_
|
||||
#define AES_CRYPTER_H_
|
||||
|
||||
typedef struct aes_crypter_t aes_crypter_t;
|
||||
|
||||
#include <crypto/crypters/crypter.h>
|
||||
|
||||
/**
|
||||
* @brief Class implementing the AES symmetric encryption algorithm.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - aes_cbc_crypter_create()
|
||||
*
|
||||
* @ingroup crypters
|
||||
* Class implementing the AES encryption algorithm.
|
||||
*/
|
||||
struct aes_cbc_crypter_t {
|
||||
struct aes_crypter_t {
|
||||
|
||||
/**
|
||||
* The crypter_t interface.
|
||||
@@ -46,16 +38,13 @@ struct aes_cbc_crypter_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor to create aes_cbc_crypter_t objects.
|
||||
*
|
||||
* Supported key sizes are: 16, 24 or 32.
|
||||
* Constructor to create aes_crypter_t objects.
|
||||
*
|
||||
* @param key_size key size in bytes
|
||||
* @return
|
||||
* - aes_cbc_crypter_t object
|
||||
* - NULL if key size not supported
|
||||
* @param algo algorithm to implement
|
||||
* @return aes_crypter_t object, NULL if not supported
|
||||
*/
|
||||
aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
|
||||
aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo,
|
||||
size_t key_size);
|
||||
|
||||
|
||||
#endif /* AES_CBC_CRYPTER_H_ */
|
||||
#endif /* AES_CRYPTER_H_ @}*/
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "aes_plugin.h"
|
||||
|
||||
#include <library.h>
|
||||
#include "aes_crypter.h"
|
||||
|
||||
typedef struct private_aes_plugin_t private_aes_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of aes_plugin
|
||||
*/
|
||||
struct private_aes_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
aes_plugin_t public;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of aes_plugin_t.destroy
|
||||
*/
|
||||
static void destroy(private_aes_plugin_t *this)
|
||||
{
|
||||
lib->crypto->remove_crypter(lib->crypto,
|
||||
(crypter_constructor_t)aes_crypter_create);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *plugin_create()
|
||||
{
|
||||
private_aes_plugin_t *this = malloc_thing(private_aes_plugin_t);
|
||||
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
|
||||
(crypter_constructor_t)aes_crypter_create);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup aes_p aes
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup aes_plugin aes_plugin
|
||||
* @{ @ingroup aes_p
|
||||
*/
|
||||
|
||||
#ifndef AES_PLUGIN_H_
|
||||
#define AES_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct aes_plugin_t aes_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing AES based algorithms in software.
|
||||
*/
|
||||
struct aes_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a aes_plugin instance.
|
||||
*/
|
||||
plugin_t *plugin_create();
|
||||
|
||||
#endif /* AES_PLUGIN_H_ @}*/
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-curl.la
|
||||
|
||||
libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
|
||||
libstrongswan_curl_la_LDFLAGS = -module
|
||||
libstrongswan_curl_la_LIBADD = -lcurl
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2007 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "curl_fetcher.h"
|
||||
|
||||
#define DEFAULT_TIMEOUT 10
|
||||
|
||||
typedef struct private_curl_fetcher_t private_curl_fetcher_t;
|
||||
|
||||
/**
|
||||
* private data of a curl_fetcher_t object.
|
||||
*/
|
||||
struct private_curl_fetcher_t {
|
||||
/**
|
||||
* Public data
|
||||
*/
|
||||
curl_fetcher_t public;
|
||||
|
||||
/**
|
||||
* CURL handle
|
||||
*/
|
||||
CURL* curl;
|
||||
|
||||
/**
|
||||
* request type, as set with FETCH_REQUEST_TYPE
|
||||
*/
|
||||
char *request_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* writes data into a dynamically resizeable chunk_t
|
||||
*/
|
||||
static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
|
||||
data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
|
||||
if (data->ptr)
|
||||
{
|
||||
memcpy(&data->ptr[data->len], ptr, realsize);
|
||||
data->len += realsize;
|
||||
}
|
||||
return realsize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements fetcher_t.fetch.
|
||||
*/
|
||||
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
|
||||
{
|
||||
struct curl_slist *headers = NULL;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
char buf[256];;
|
||||
status_t status;
|
||||
|
||||
*result = chunk_empty;
|
||||
|
||||
if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK)
|
||||
{ /* URL type not supported by curl */
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, error);
|
||||
curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
|
||||
curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
|
||||
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
|
||||
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
|
||||
curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
|
||||
if (this->request_type)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
|
||||
headers = curl_slist_append(headers, buf);
|
||||
curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
|
||||
}
|
||||
|
||||
DBG2("sending http request to '%s'...", uri);
|
||||
switch (curl_easy_perform(this->curl))
|
||||
{
|
||||
case CURLE_UNSUPPORTED_PROTOCOL:
|
||||
status = NOT_SUPPORTED;
|
||||
break;
|
||||
case CURLE_OK:
|
||||
status = SUCCESS;
|
||||
break;
|
||||
default:
|
||||
DBG1("libcurl http request failed: %s", error);
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
curl_slist_free_all(headers);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of fetcher_t.set_option.
|
||||
*/
|
||||
static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, option);
|
||||
switch (option)
|
||||
{
|
||||
case FETCH_REQUEST_DATA:
|
||||
{
|
||||
chunk_t data = va_arg(args, chunk_t);
|
||||
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, data.ptr);
|
||||
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
|
||||
return TRUE;
|
||||
}
|
||||
case FETCH_REQUEST_TYPE:
|
||||
{
|
||||
this->request_type = va_arg(args, char*);
|
||||
return TRUE;
|
||||
}
|
||||
case FETCH_TIMEOUT:
|
||||
{
|
||||
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT,
|
||||
va_arg(args, u_int));
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements fetcher_t.destroy
|
||||
*/
|
||||
static void destroy(private_curl_fetcher_t *this)
|
||||
{
|
||||
curl_easy_cleanup(this->curl);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
curl_fetcher_t *curl_fetcher_create()
|
||||
{
|
||||
private_curl_fetcher_t *this = malloc_thing(private_curl_fetcher_t);
|
||||
|
||||
this->curl = curl_easy_init();
|
||||
if (this->curl == NULL)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->request_type = NULL;
|
||||
|
||||
this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
|
||||
this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
|
||||
this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup curl_fetcher curl_fetcher
|
||||
* @{ @ingroup curl_p
|
||||
*/
|
||||
|
||||
#ifndef CURL_FETCHER_H_
|
||||
#define CURL_FETCHER_H_
|
||||
|
||||
typedef struct curl_fetcher_t curl_fetcher_t;
|
||||
|
||||
/**
|
||||
* Fetcher implementation using libcurl
|
||||
*/
|
||||
struct curl_fetcher_t {
|
||||
|
||||
/**
|
||||
* Implements fetcher interface
|
||||
*/
|
||||
fetcher_t interface;
|
||||
|
||||
/**
|
||||
* Destroy a curl_fetcher instance.
|
||||
*/
|
||||
void (*destroy)(curl_fetcher_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a curl_fetcher instance.
|
||||
*/
|
||||
curl_fetcher_t *curl_fetcher_create();
|
||||
|
||||
#endif /* CURL_FETCHER_H_ @}*/
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "curl_plugin.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <debug.h>
|
||||
#include "curl_fetcher.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef struct private_curl_plugin_t private_curl_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of curl_plugin
|
||||
*/
|
||||
struct private_curl_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
curl_plugin_t public;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of curl_plugin_t.curltroy
|
||||
*/
|
||||
static void destroy(private_curl_plugin_t *this)
|
||||
{
|
||||
lib->fetcher->remove_fetcher(lib->fetcher,
|
||||
(fetcher_constructor_t)curl_fetcher_create);
|
||||
curl_global_cleanup();
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *plugin_create()
|
||||
{
|
||||
CURLcode res;
|
||||
private_curl_plugin_t *this = malloc_thing(private_curl_plugin_t);
|
||||
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
res = curl_global_init(CURL_GLOBAL_NOTHING);
|
||||
if (res == CURLE_OK)
|
||||
{
|
||||
lib->fetcher->add_fetcher(lib->fetcher,
|
||||
(fetcher_constructor_t)curl_fetcher_create, "file://");
|
||||
lib->fetcher->add_fetcher(lib->fetcher,
|
||||
(fetcher_constructor_t)curl_fetcher_create, "http://");
|
||||
lib->fetcher->add_fetcher(lib->fetcher,
|
||||
(fetcher_constructor_t)curl_fetcher_create, "https://");
|
||||
lib->fetcher->add_fetcher(lib->fetcher,
|
||||
(fetcher_constructor_t)curl_fetcher_create, "ftp://");
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1("global libcurl initializing failed: %s, curl disabled",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup curl_p curl
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup curl_plugin curl_plugin
|
||||
* @{ @ingroup curl_p
|
||||
*/
|
||||
|
||||
#ifndef CURL_PLUGIN_H_
|
||||
#define CURL_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct curl_plugin_t curl_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing fetcher interface using libcurl http library.
|
||||
*/
|
||||
struct curl_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a curl_plugin instance.
|
||||
*/
|
||||
plugin_t *plugin_create();
|
||||
|
||||
#endif /* CURL_PLUGIN_H_ @}*/
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-des.la
|
||||
|
||||
libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
|
||||
libstrongswan_des_la_LDFLAGS = -module
|
||||
|
||||
+2
-7
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file des_crypter.c
|
||||
*
|
||||
* @brief Implementation of des_crypter_t
|
||||
*
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -61,6 +54,8 @@
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "des_crypter.h"
|
||||
+10
-19
@@ -1,12 +1,5 @@
|
||||
/**
|
||||
* @file des_crypter.h
|
||||
*
|
||||
* @brief Interface of des_crypter_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Copyright (C) 2006-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -20,6 +13,11 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup des_crypter des_crypter
|
||||
* @{ @ingroup des_p
|
||||
*/
|
||||
|
||||
#ifndef DES_CRYPTER_H_
|
||||
#define DES_CRYPTER_H_
|
||||
|
||||
@@ -29,12 +27,7 @@ typedef struct des_crypter_t des_crypter_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Class implementing the DES and 3DES encryption algorithms.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - des_crypter_create()
|
||||
*
|
||||
* @ingroup crypters
|
||||
* Class implementing the DES and 3DES encryption algorithms.
|
||||
*/
|
||||
struct des_crypter_t {
|
||||
|
||||
@@ -45,14 +38,12 @@ struct des_crypter_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor to create des_crypter_t objects.
|
||||
* Constructor to create des_crypter_t objects.
|
||||
*
|
||||
* @param algo ENCR_DES for single DES, ENCR_3DES for triple DES
|
||||
* @return
|
||||
* - des_crypter_t object
|
||||
* - NULL if algo not supported
|
||||
* @return des_crypter_t object, NULL if algo not supported
|
||||
*/
|
||||
des_crypter_t *des_crypter_create(encryption_algorithm_t algo);
|
||||
|
||||
|
||||
#endif /* DES_CRYPTER_H_ */
|
||||
#endif /* DES_CRYPTER_H_ @}*/
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "des_plugin.h"
|
||||
|
||||
#include <library.h>
|
||||
#include "des_crypter.h"
|
||||
|
||||
typedef struct private_des_plugin_t private_des_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of des_plugin
|
||||
*/
|
||||
struct private_des_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
des_plugin_t public;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of des_plugin_t.destroy
|
||||
*/
|
||||
static void destroy(private_des_plugin_t *this)
|
||||
{
|
||||
lib->crypto->remove_crypter(lib->crypto,
|
||||
(crypter_constructor_t)des_crypter_create);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *plugin_create()
|
||||
{
|
||||
private_des_plugin_t *this = malloc_thing(private_des_plugin_t);
|
||||
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
lib->crypto->add_crypter(lib->crypto, ENCR_DES,
|
||||
(crypter_constructor_t)des_crypter_create);
|
||||
lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
|
||||
(crypter_constructor_t)des_crypter_create);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup des_p des
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup des_plugin des_plugin
|
||||
* @{ @ingroup des_p
|
||||
*/
|
||||
|
||||
#ifndef DES_PLUGIN_H_
|
||||
#define DES_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct des_plugin_t des_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing DES based algorithms in software.
|
||||
*/
|
||||
struct des_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a des_plugin instance.
|
||||
*/
|
||||
plugin_t *plugin_create();
|
||||
|
||||
#endif /* DES_PLUGIN_H_ @}*/
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-fips-prf.la
|
||||
|
||||
libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
|
||||
libstrongswan_fips_prf_la_LDFLAGS = -module
|
||||
|
||||
+39
-36
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file fips_prf.c
|
||||
*
|
||||
* @brief Implementation for fips_prf_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
@@ -18,6 +11,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "fips_prf.h"
|
||||
@@ -47,10 +42,15 @@ struct private_fips_prf_t {
|
||||
*/
|
||||
size_t b;
|
||||
|
||||
/**
|
||||
* associated hasher when using SHA1 mode
|
||||
*/
|
||||
hasher_t *hasher;
|
||||
|
||||
/**
|
||||
* G function, either SHA1 or DES
|
||||
*/
|
||||
void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]);
|
||||
void (*g)(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[]);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -61,6 +61,7 @@ static u_int8_t t[] = {
|
||||
0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* sum = (a + b) mod 2 ^ (length * 8)
|
||||
*/
|
||||
@@ -139,7 +140,7 @@ static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
|
||||
add_mod(this->b, xkey, xseed, xval);
|
||||
DBG3("XVAL %b", xval, this->b);
|
||||
/* b. wi = G(t, XVAL ) */
|
||||
this->g(t, xval_chunk, &w[i * this->b]);
|
||||
this->g(this, t, xval_chunk, &w[i * this->b]);
|
||||
DBG3("w[%d] %b", i, &w[i * this->b], this->b);
|
||||
/* c. XKEY = (1 + XKEY + wi) mod 2b */
|
||||
add_mod(this->b, xkey, &w[i * this->b], sum);
|
||||
@@ -186,12 +187,9 @@ static void set_key(private_fips_prf_t *this, chunk_t key)
|
||||
/**
|
||||
* Implementation of the G() function based on SHA1
|
||||
*/
|
||||
void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
|
||||
void g_sha1(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[])
|
||||
{
|
||||
hasher_t *hasher;
|
||||
u_int8_t buf[64];
|
||||
chunk_t state_chunk;
|
||||
u_int32_t *state, *iv, *hash;
|
||||
|
||||
if (c.len < sizeof(buf))
|
||||
{
|
||||
@@ -207,24 +205,8 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
|
||||
c.len = sizeof(buf);
|
||||
}
|
||||
|
||||
/* our SHA1 hasher's state is 32-Bit integers in host order. We must
|
||||
* convert them */
|
||||
hasher = hasher_create(HASH_SHA1);
|
||||
state_chunk = hasher->get_state(hasher);
|
||||
state = (u_int32_t*)state_chunk.ptr;
|
||||
iv = (u_int32_t*)t;
|
||||
hash = (u_int32_t*)res;
|
||||
state[0] = htonl(iv[0]);
|
||||
state[1] = htonl(iv[1]);
|
||||
state[2] = htonl(iv[2]);
|
||||
state[3] = htonl(iv[3]);
|
||||
hasher->get_hash(hasher, c, NULL);
|
||||
hash[0] = htonl(state[0]);
|
||||
hash[1] = htonl(state[1]);
|
||||
hash[2] = htonl(state[2]);
|
||||
hash[3] = htonl(state[3]);
|
||||
hash[4] = htonl(state[4]);
|
||||
hasher->destroy(hasher);
|
||||
/* calculate the special (HASH_SHA1_STATE) hash*/
|
||||
this->hasher->get_hash(this->hasher, c, res);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,6 +214,7 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
|
||||
*/
|
||||
static void destroy(private_fips_prf_t *this)
|
||||
{
|
||||
this->hasher->destroy(this->hasher);
|
||||
free(this->key);
|
||||
free(this);
|
||||
}
|
||||
@@ -239,7 +222,7 @@ static void destroy(private_fips_prf_t *this)
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
|
||||
fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
|
||||
{
|
||||
private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
|
||||
|
||||
@@ -250,9 +233,29 @@ fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
|
||||
this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
|
||||
this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
|
||||
|
||||
this->g = g;
|
||||
this->b = b;
|
||||
this->key = malloc(b);
|
||||
switch (algo)
|
||||
{
|
||||
case PRF_FIPS_SHA1_160:
|
||||
{
|
||||
this->g = g_sha1;
|
||||
this->b = 20;
|
||||
this->hasher = lib->crypto->create_hasher(lib->crypto,
|
||||
HASH_SHA1_NOFINAL);
|
||||
if (this->hasher == NULL)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PRF_FIPS_DES:
|
||||
/* not implemented yet */
|
||||
default:
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->key = malloc(this->b);
|
||||
|
||||
return &(this->public);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user