More documentation
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22275 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
2007-12-11 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||||
|
|
||||||
|
* *.[ch]: More documentation
|
||||||
|
|
||||||
2007-12-09 Love H<>rnquist <20>strand <lha@it.su.se>
|
2007-12-09 Love H<>rnquist <20>strand <lha@it.su.se>
|
||||||
|
|
||||||
* handle refcount on NULL.
|
* handle refcount on NULL.
|
||||||
|
@@ -36,6 +36,19 @@ RCSID("$Id$");
|
|||||||
#include "crypto-headers.h"
|
#include "crypto-headers.h"
|
||||||
#include <rtbl.h>
|
#include <rtbl.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_cert The basic certificate
|
||||||
|
*
|
||||||
|
* The basic hx509 cerificate object in hx509 is hx509_cert. The
|
||||||
|
* hx509_cert object is representing one X509/PKIX certificate and
|
||||||
|
* associated attributes; like private key, friendly name, etc.
|
||||||
|
*
|
||||||
|
* A hx509_cert object is usully found via the keyset interfaces (@ref
|
||||||
|
* page_keyset), but its also possible to create a certificate
|
||||||
|
* directly from a parsed object with hx509_cert_init() and
|
||||||
|
* hx509_cert_init_data().
|
||||||
|
*/
|
||||||
|
|
||||||
struct hx509_verify_ctx_data {
|
struct hx509_verify_ctx_data {
|
||||||
hx509_certs trust_anchors;
|
hx509_certs trust_anchors;
|
||||||
int flags;
|
int flags;
|
||||||
|
@@ -34,9 +34,42 @@
|
|||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_cms CMS/PKCS7 message functions.
|
||||||
|
*
|
||||||
|
* CMS is defined in RFC 3369 and is an continuation of the RSA Labs
|
||||||
|
* standard PKCS7. The basic messages in CMS is
|
||||||
|
*
|
||||||
|
* - SignedData
|
||||||
|
* Data signed with private key (RSA, DSA, ECDSA) or secret
|
||||||
|
* (symmetric) key
|
||||||
|
* - EnvelopedData
|
||||||
|
* Data encrypted with private key (RSA)
|
||||||
|
* - EncryptedData
|
||||||
|
* Data encrypted with secret (symmetric) key.
|
||||||
|
* - ContentInfo
|
||||||
|
* Wrapper structure including type and data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
|
#define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
|
||||||
#define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
|
#define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap data and oid in a ContentInfo and encode it.
|
||||||
|
*
|
||||||
|
* @param oid type of the content.
|
||||||
|
* @param buf data to be wrapped. If a NULL pointer is passed in, the
|
||||||
|
* optional content field in the ContentInfo is not going be filled
|
||||||
|
* in.
|
||||||
|
* @param res the encoded buffer, the result should be freed with
|
||||||
|
* der_free_octet_string().
|
||||||
|
*
|
||||||
|
* @return Returns an hx509 error code.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_cms
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_cms_wrap_ContentInfo(const heim_oid *oid,
|
hx509_cms_wrap_ContentInfo(const heim_oid *oid,
|
||||||
const heim_octet_string *buf,
|
const heim_octet_string *buf,
|
||||||
@@ -52,6 +85,7 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
|
|||||||
ret = der_copy_oid(oid, &ci.contentType);
|
ret = der_copy_oid(oid, &ci.contentType);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
if (buf) {
|
||||||
ALLOC(ci.content, 1);
|
ALLOC(ci.content, 1);
|
||||||
if (ci.content == NULL) {
|
if (ci.content == NULL) {
|
||||||
free_ContentInfo(&ci);
|
free_ContentInfo(&ci);
|
||||||
@@ -64,6 +98,7 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
|
|||||||
}
|
}
|
||||||
memcpy(ci.content->data, buf->data, buf->length);
|
memcpy(ci.content->data, buf->data, buf->length);
|
||||||
ci.content->length = buf->length;
|
ci.content->length = buf->length;
|
||||||
|
}
|
||||||
|
|
||||||
ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret);
|
ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret);
|
||||||
free_ContentInfo(&ci);
|
free_ContentInfo(&ci);
|
||||||
@@ -75,6 +110,20 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode an ContentInfo and unwrap data and oid it.
|
||||||
|
*
|
||||||
|
* @param in the encoded buffer.
|
||||||
|
* @param oid type of the content.
|
||||||
|
* @param buf data to be wrapped.
|
||||||
|
* @param have_data since the data is optional, this flags show dthe
|
||||||
|
* diffrence between no data and the zero length data.
|
||||||
|
*
|
||||||
|
* @return Returns an hx509 error code.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_cms
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
|
hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
|
||||||
heim_oid *oid,
|
heim_oid *oid,
|
||||||
@@ -108,7 +157,7 @@ hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
|
|||||||
memset(out, 0, sizeof(*out));
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
if (have_data)
|
if (have_data)
|
||||||
*have_data = (ci.content != NULL) ? 1 : 0;
|
*have_data = (ci.vcontent != NULL) ? 1 : 0;
|
||||||
|
|
||||||
free_ContentInfo(&ci);
|
free_ContentInfo(&ci);
|
||||||
|
|
||||||
@@ -267,6 +316,23 @@ find_CMSIdentifier(hx509_context context,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode and unencrypt EnvelopedData.
|
||||||
|
*
|
||||||
|
* Separate data from the EnvelopedData.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param certs
|
||||||
|
* @param flags
|
||||||
|
* @param data
|
||||||
|
* @param length
|
||||||
|
* @param encryptedContent
|
||||||
|
* @param contentType
|
||||||
|
* @param content
|
||||||
|
*
|
||||||
|
* @ingroup hx509_cms
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_cms_unenvelope(hx509_context context,
|
hx509_cms_unenvelope(hx509_context context,
|
||||||
hx509_certs certs,
|
hx509_certs certs,
|
||||||
|
@@ -31,23 +31,38 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \mainpage Heimdal X.509 library
|
/** @mainpage Heimdal PKIX/X.509 library
|
||||||
*
|
*
|
||||||
* \section intro Introduction
|
* @section intro Introduction
|
||||||
*
|
*
|
||||||
* Heimdal libhx509 library is a implementation of the X.509 and
|
* Heimdal libhx509 library is a implementation of the PKIX/X.509 and
|
||||||
* related protocols.
|
* related protocols.
|
||||||
*
|
*
|
||||||
* X.509 is ...
|
* PKIX/X.509 is ...
|
||||||
*
|
*
|
||||||
* The project web page:\n
|
*
|
||||||
|
* Sections in this manual are:
|
||||||
|
* - @ref page_name
|
||||||
|
* - @ref page_cert
|
||||||
|
* - @ref page_keyset
|
||||||
|
* - @ref page_revoke
|
||||||
|
* - @ref page_cms
|
||||||
|
*
|
||||||
|
* The project web page:
|
||||||
* http://www.h5l.org/
|
* http://www.h5l.org/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup hx509 hx509 library */
|
/** @defgroup hx509 hx509 library */
|
||||||
/** @defgroup hx509_cert hx509 certificate functions */
|
|
||||||
/** @defgroup hx509_verify hx509 verification functions */
|
/** @defgroup hx509_cert hx509 certificate functions
|
||||||
/** @defgroup hx509_name hx509 name functions */
|
* See the @ref page_cert for description and examples. */
|
||||||
|
/** @defgroup hx509_cms hx509 name functions
|
||||||
|
* See the @ref page_cms for description and examples. */
|
||||||
/** @defgroup hx509_crypto hx509 crypto functions */
|
/** @defgroup hx509_crypto hx509 crypto functions */
|
||||||
/** @defgroup hx509_misc hx509 misc functions */
|
/** @defgroup hx509_misc hx509 misc functions */
|
||||||
|
/** @defgroup hx509_name hx509 name functions
|
||||||
|
* See the @ref page_name for description and examples. */
|
||||||
|
/** @defgroup hx509_revoke hx509 revokation checking functions
|
||||||
|
* See the @ref page_revoke for description and examples. */
|
||||||
|
/** @defgroup hx509_verify hx509 verification functions */
|
||||||
|
@@ -34,6 +34,11 @@
|
|||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_keyset Keyset operations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
struct hx509_certs_data {
|
struct hx509_certs_data {
|
||||||
int ref;
|
int ref;
|
||||||
struct hx509_keyset_ops *ops;
|
struct hx509_keyset_ops *ops;
|
||||||
|
101
lib/hx509/name.c
101
lib/hx509/name.c
@@ -34,10 +34,28 @@
|
|||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* name parsing from rfc2253
|
* @page page_name PKIX/X.509 Names
|
||||||
* fix so parsing rfc1779 works too
|
*
|
||||||
* rfc3280
|
* There are several names in PKIX/X.509, GeneralName and Name.
|
||||||
|
*
|
||||||
|
* A Name consists of an ordered list of Relative Distinguished Names
|
||||||
|
* (RDN). Each RDN consists of an unordered list of typed strings. The
|
||||||
|
* types are defined by OID and have long and short description. For
|
||||||
|
* example id-at-commonName (2.5.4.3) have the long name CommonName
|
||||||
|
* and short name CN. The string itself can be of serveral encoding,
|
||||||
|
* UTF8, UTF16, Teltex string, etc. The type limit what encoding
|
||||||
|
* should be used.
|
||||||
|
*
|
||||||
|
* GeneralName is a broader nametype that can contains al kind of
|
||||||
|
* stuff like Name, IP addresses, partial Name, etc.
|
||||||
|
*
|
||||||
|
* Name is mapped into a hx509_name object.
|
||||||
|
*
|
||||||
|
* Parse and string name into a hx509_name object with hx509_parse_name(),
|
||||||
|
* make it back into string representation with hx509_name_to_string().
|
||||||
|
*
|
||||||
|
* Name string are defined rfc2253, rfc1779 and X.501.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@@ -385,19 +403,6 @@ _hx509_name_from_Name(const Name *n, hx509_name *name)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
hx509_der_parse_name(const void *data, size_t length, hx509_name *name)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
Name n;
|
|
||||||
|
|
||||||
*name = NULL;
|
|
||||||
ret = decode_Name(data, length, &n, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
return _hx509_name_from_Name(&n, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_hx509_name_modify(hx509_context context,
|
_hx509_name_modify(hx509_context context,
|
||||||
Name *name,
|
Name *name,
|
||||||
@@ -577,6 +582,17 @@ hx509_name_copy(hx509_context context, const hx509_name from, hx509_name *to)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a hx509_name into a Name.
|
||||||
|
*
|
||||||
|
* @param from the name to copy from
|
||||||
|
* @param to the name to copy to
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_name
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_name_to_Name(const hx509_name from, Name *to)
|
hx509_name_to_Name(const hx509_name from, Name *to)
|
||||||
{
|
{
|
||||||
@@ -589,6 +605,19 @@ hx509_name_normalize(hx509_context context, hx509_name name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands variables in the name using env. Variables are on the form
|
||||||
|
* ${name}. Useful when dealing with certificate templates.
|
||||||
|
*
|
||||||
|
* @param context A hx509 cotext.
|
||||||
|
* @param name the name to expand.
|
||||||
|
* @param env environment variable to expand.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_name
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_name_expand(hx509_context context,
|
hx509_name_expand(hx509_context context,
|
||||||
hx509_name name,
|
hx509_name name,
|
||||||
@@ -607,6 +636,7 @@ hx509_name_expand(hx509_context context,
|
|||||||
|
|
||||||
for (i = 0 ; i < n->u.rdnSequence.len; i++) {
|
for (i = 0 ; i < n->u.rdnSequence.len; i++) {
|
||||||
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
|
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
|
||||||
|
/** Only UTF8String rdnSequence names are allowed */
|
||||||
/*
|
/*
|
||||||
THIS SHOULD REALLY BE:
|
THIS SHOULD REALLY BE:
|
||||||
COMP = n->u.rdnSequence.val[i].val[j];
|
COMP = n->u.rdnSequence.val[i].val[j];
|
||||||
@@ -704,7 +734,7 @@ hx509_name_free(hx509_name *name)
|
|||||||
* Convert a DER encoded name info a string.
|
* Convert a DER encoded name info a string.
|
||||||
*
|
*
|
||||||
* @param data data to a DER/BER encoded name
|
* @param data data to a DER/BER encoded name
|
||||||
? * @param length length of data
|
* @param length length of data
|
||||||
* @param str the resulting string, is NULL on failure.
|
* @param str the resulting string, is NULL on failure.
|
||||||
*
|
*
|
||||||
* @return An hx509 error code, see hx509_get_error_string().
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
@@ -712,22 +742,34 @@ hx509_name_free(hx509_name *name)
|
|||||||
* @ingroup hx509_name
|
* @ingroup hx509_name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_unparse_der_name(const void *data, size_t length, char **str)
|
hx509_unparse_der_name(const void *data, size_t length, char **str)
|
||||||
{
|
{
|
||||||
hx509_name name;
|
Name name;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = hx509_der_parse_name(data, length, &name);
|
*str = NULL;
|
||||||
|
|
||||||
|
ret = decode_Name(data, length, &name, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
ret = _hx509_Name_to_string(&name, str);
|
||||||
ret = hx509_name_to_string(name, str);
|
free_Name(&name);
|
||||||
hx509_name_free(&name);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a hx509_name object to DER encoded name.
|
||||||
|
*
|
||||||
|
* @param name name to concert
|
||||||
|
* @param data data to a DER encoded name
|
||||||
|
* @param length length of data
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_name
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_name_to_der_name(const hx509_name name, void **data, size_t *length)
|
hx509_name_to_der_name(const hx509_name name, void **data, size_t *length)
|
||||||
{
|
{
|
||||||
@@ -743,7 +785,6 @@ hx509_name_to_der_name(const hx509_name name, void **data, size_t *length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_hx509_unparse_Name(const Name *aname, char **str)
|
_hx509_unparse_Name(const Name *aname, char **str)
|
||||||
{
|
{
|
||||||
@@ -759,6 +800,16 @@ _hx509_unparse_Name(const Name *aname, char **str)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unparse the hx509 name in name into a string.
|
||||||
|
*
|
||||||
|
* @param name the name to check if its empty/null.
|
||||||
|
*
|
||||||
|
* @return non zero if the name is empty/null.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_name
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_name_is_null_p(const hx509_name name)
|
hx509_name_is_null_p(const hx509_name name)
|
||||||
{
|
{
|
||||||
|
@@ -31,6 +31,24 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_revoke Revocation methods
|
||||||
|
*
|
||||||
|
* There are two revocation method for PKIX/X.509: CRL and OCSP.
|
||||||
|
* Revocation is needed if the private key is lost and
|
||||||
|
* stolen. Depending on how picky you are, you might want to make
|
||||||
|
* revocation for destroyed private keys too (smartcard broken), but
|
||||||
|
* that should not be a problem.
|
||||||
|
*
|
||||||
|
* CRL is a list of certifiates that have expired.
|
||||||
|
*
|
||||||
|
* OCSP is an online checking method where the requestor sends a list
|
||||||
|
* of certificates to the OCSP server to return a signed reply if they
|
||||||
|
* are valid or not. Some services sends a OCSP reply as part of the
|
||||||
|
* hand-shake to make the revoktion decision simpler/faster for the
|
||||||
|
* client.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "hx_locl.h"
|
#include "hx_locl.h"
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
@@ -63,6 +81,17 @@ struct hx509_revoke_ctx_data {
|
|||||||
} ocsps;
|
} ocsps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a revokation context. Free with hx509_revoke_free().
|
||||||
|
*
|
||||||
|
* @param context A hx509 context.
|
||||||
|
* @param ctx returns a newly allocated revokation context.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
|
hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
|
||||||
{
|
{
|
||||||
@@ -101,6 +130,14 @@ free_ocsp(struct revoke_ocsp *ocsp)
|
|||||||
hx509_cert_free(ocsp->signer);
|
hx509_cert_free(ocsp->signer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a hx509 revokation context.
|
||||||
|
*
|
||||||
|
* @param ctx context to be freed
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
hx509_revoke_free(hx509_revoke_ctx *ctx)
|
hx509_revoke_free(hx509_revoke_ctx *ctx)
|
||||||
{
|
{
|
||||||
@@ -345,6 +382,18 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a OCSP file to the revokation context.
|
||||||
|
*
|
||||||
|
* @param context hx509 context
|
||||||
|
* @param ctx hx509 revokation context
|
||||||
|
* @param path path to file that is going to be added to the context.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_revoke_add_ocsp(hx509_context context,
|
hx509_revoke_add_ocsp(hx509_context context,
|
||||||
hx509_revoke_ctx ctx,
|
hx509_revoke_ctx ctx,
|
||||||
@@ -537,6 +586,18 @@ load_crl(const char *path, time_t *t, CRLCertificateList *crl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a CRL file to the revokation context.
|
||||||
|
*
|
||||||
|
* @param context hx509 context
|
||||||
|
* @param ctx hx509 revokation context
|
||||||
|
* @param path path to file that is going to be added to the context.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_revoke_add_crl(hx509_context context,
|
hx509_revoke_add_crl(hx509_context context,
|
||||||
hx509_revoke_ctx ctx,
|
hx509_revoke_ctx ctx,
|
||||||
@@ -589,6 +650,23 @@ hx509_revoke_add_crl(hx509_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that a certificate is not expired according to a revokation
|
||||||
|
* context. Also need the parent certificte to the check OCSP
|
||||||
|
* parent identifier.
|
||||||
|
*
|
||||||
|
* @param context hx509 context
|
||||||
|
* @param ctx hx509 revokation context
|
||||||
|
* @param certs
|
||||||
|
* @param now
|
||||||
|
* @param cert
|
||||||
|
* @param parent_cert
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_revoke_verify(hx509_context context,
|
hx509_revoke_verify(hx509_context context,
|
||||||
@@ -861,6 +939,22 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an OCSP request for a set of certificates.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context
|
||||||
|
* @param reqcerts list of certificates to request ocsp data for
|
||||||
|
* @param pool certificate pool to use when signing
|
||||||
|
* @param signer certificate to use to sign the request
|
||||||
|
* @param digest the signing algorithm in the request, if NULL use the
|
||||||
|
* default signature algorithm,
|
||||||
|
* @param request the encoded request, free with free_heim_octet_string().
|
||||||
|
* @param nonce nonce in the request, free with free_heim_octet_string().
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_ocsp_request(hx509_context context,
|
hx509_ocsp_request(hx509_context context,
|
||||||
@@ -889,41 +983,49 @@ hx509_ocsp_request(hx509_context context,
|
|||||||
|
|
||||||
ret = hx509_certs_iter(context, reqcerts, add_to_req, &ctx);
|
ret = hx509_certs_iter(context, reqcerts, add_to_req, &ctx);
|
||||||
hx509_cert_free(ctx.parent);
|
hx509_cert_free(ctx.parent);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (nonce) {
|
||||||
|
req.tbsRequest.requestExtensions =
|
||||||
|
calloc(1, sizeof(*req.tbsRequest.requestExtensions));
|
||||||
|
if (req.tbsRequest.requestExtensions == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
es = req.tbsRequest.requestExtensions;
|
||||||
|
|
||||||
|
es->val = calloc(es->len, sizeof(es->val[0]));
|
||||||
|
if (es->val == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
es->len = 1;
|
||||||
|
|
||||||
|
ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_OCSPRequest(&req);
|
free_OCSPRequest(&req);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonce) {
|
|
||||||
|
|
||||||
req.tbsRequest.requestExtensions =
|
|
||||||
calloc(1, sizeof(*req.tbsRequest.requestExtensions));
|
|
||||||
if (req.tbsRequest.requestExtensions == NULL) {
|
|
||||||
free_OCSPRequest(&req);
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
es = req.tbsRequest.requestExtensions;
|
|
||||||
|
|
||||||
es->len = 1;
|
|
||||||
es->val = calloc(es->len, sizeof(es->val[0]));
|
|
||||||
|
|
||||||
ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);
|
|
||||||
if (ret)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
es->val[0].extnValue.data = malloc(10);
|
es->val[0].extnValue.data = malloc(10);
|
||||||
if (es->val[0].extnValue.data == NULL) {
|
if (es->val[0].extnValue.data == NULL) {
|
||||||
free_OCSPRequest(&req);
|
ret = ENOMEM;
|
||||||
return ENOMEM;
|
goto out;
|
||||||
}
|
}
|
||||||
es->val[0].extnValue.length = 10;
|
es->val[0].extnValue.length = 10;
|
||||||
|
|
||||||
ret = RAND_bytes(es->val[0].extnValue.data,
|
ret = RAND_bytes(es->val[0].extnValue.data,
|
||||||
es->val[0].extnValue.length);
|
es->val[0].extnValue.length);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
free_OCSPRequest(&req);
|
ret = HX509_CRYPTO_INTERNAL_ERROR;
|
||||||
return HX509_CRYPTO_INTERNAL_ERROR;
|
goto out;
|
||||||
|
}
|
||||||
|
ret = der_copy_octet_string(nonce, &es->val[0].extnValue);
|
||||||
|
if (ret) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,12 +1033,15 @@ hx509_ocsp_request(hx509_context context,
|
|||||||
&req, &size, ret);
|
&req, &size, ret);
|
||||||
free_OCSPRequest(&req);
|
free_OCSPRequest(&req);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
if (size != request->length)
|
if (size != request->length)
|
||||||
_hx509_abort("internal ASN.1 encoder error");
|
_hx509_abort("internal ASN.1 encoder error");
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free_OCSPRequest(&req);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@@ -948,6 +1053,18 @@ printable_time(time_t t)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the OCSP reply stored in a file.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context
|
||||||
|
* @param path path to a file with a OCSP reply
|
||||||
|
* @param out the out FILE descriptor to print the reply on
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_revoke
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
|
hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
|
||||||
{
|
{
|
||||||
@@ -1035,10 +1152,23 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Verify that the `cert' is part of the OCSP reply and it's not
|
* Verify that the certificate is part of the OCSP reply and it's not
|
||||||
* expired. Doesn't verify signature the OCSP reply or it's done by a
|
* expired. Doesn't verify signature the OCSP reply or it's done by a
|
||||||
* authorized sender, that is assumed to be already done.
|
* authorized sender, that is assumed to be already done.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context
|
||||||
|
* @param now the time right now, if 0, use the current time.
|
||||||
|
* @param cert the certificate to verify
|
||||||
|
* @param flags flags control the behavior
|
||||||
|
* @param data pointer to the encode ocsp reply
|
||||||
|
* @param length the length of the encode ocsp reply
|
||||||
|
* @param expiration return the time the OCSP will expire and need to
|
||||||
|
* be rechecked.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -1138,6 +1268,17 @@ struct hx509_crl {
|
|||||||
time_t expire;
|
time_t expire;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a CRL context. Use hx509_crl_free() to free the CRL context.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context.
|
||||||
|
* @param crl return pointer to a newly allocated CRL context.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_crl_alloc(hx509_context context, hx509_crl *crl)
|
hx509_crl_alloc(hx509_context context, hx509_crl *crl)
|
||||||
{
|
{
|
||||||
@@ -1159,6 +1300,18 @@ hx509_crl_alloc(hx509_context context, hx509_crl *crl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add revoked certificate to an CRL context.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context.
|
||||||
|
* @param crl the CRL to add the revoked certificate to.
|
||||||
|
* @param certs keyset of certificate to revoke.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_crl_add_revoked_certs(hx509_context context,
|
hx509_crl_add_revoked_certs(hx509_context context,
|
||||||
hx509_crl crl,
|
hx509_crl crl,
|
||||||
@@ -1167,6 +1320,19 @@ hx509_crl_add_revoked_certs(hx509_context context,
|
|||||||
return hx509_certs_merge(context, crl->revoked, certs);
|
return hx509_certs_merge(context, crl->revoked, certs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the lifetime of a CRL context.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context.
|
||||||
|
* @param crl a CRL context
|
||||||
|
* @param delta delta time the certificate is valid, library adds the
|
||||||
|
* current time to this.
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
|
hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
|
||||||
{
|
{
|
||||||
@@ -1174,6 +1340,14 @@ hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a CRL context.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context.
|
||||||
|
* @param crl a CRL context to free.
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
hx509_crl_free(hx509_context context, hx509_crl *crl)
|
hx509_crl_free(hx509_context context, hx509_crl *crl)
|
||||||
@@ -1220,6 +1394,19 @@ add_revoked(hx509_context context, void *ctx, hx509_cert cert)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a CRL and return an encode certificate.
|
||||||
|
*
|
||||||
|
* @param context a hx509 context.
|
||||||
|
* @param signer certificate to sign the CRL with
|
||||||
|
* @param crl the CRL to sign
|
||||||
|
* @param os return the signed and encoded CRL, free with
|
||||||
|
* free_heim_octet_string()
|
||||||
|
*
|
||||||
|
* @return An hx509 error code, see hx509_get_error_string().
|
||||||
|
*
|
||||||
|
* @ingroup hx509_verify
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
hx509_crl_sign(hx509_context context,
|
hx509_crl_sign(hx509_context context,
|
||||||
|
Reference in New Issue
Block a user