parsing of generalNames is not needed any more
This commit is contained in:
@@ -67,62 +67,6 @@ static const asn1Object_t authKeyIdentifierObjects[] = {
|
|||||||
#define AUTH_KEY_ID_CERT_ISSUER 3
|
#define AUTH_KEY_ID_CERT_ISSUER 3
|
||||||
#define AUTH_KEY_ID_CERT_SERIAL 5
|
#define AUTH_KEY_ID_CERT_SERIAL 5
|
||||||
|
|
||||||
/**
|
|
||||||
* ASN.1 definition of generalNames
|
|
||||||
*/
|
|
||||||
static const asn1Object_t generalNamesObjects[] = {
|
|
||||||
{ 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
|
|
||||||
{ 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
|
|
||||||
{ 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
|
|
||||||
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
|
|
||||||
};
|
|
||||||
#define GENERAL_NAMES_GN 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ASN.1 definition of generalName
|
|
||||||
*/
|
|
||||||
static const asn1Object_t generalNameObjects[] = {
|
|
||||||
{ 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
|
|
||||||
{ 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
|
|
||||||
{ 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
|
|
||||||
{ 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
|
|
||||||
{ 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
|
|
||||||
{ 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
|
|
||||||
{ 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
|
|
||||||
{ 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
|
|
||||||
{ 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
|
|
||||||
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
|
|
||||||
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
|
|
||||||
};
|
|
||||||
#define GN_OBJ_OTHER_NAME 0
|
|
||||||
#define GN_OBJ_RFC822_NAME 2
|
|
||||||
#define GN_OBJ_DNS_NAME 4
|
|
||||||
#define GN_OBJ_X400_ADDRESS 6
|
|
||||||
#define GN_OBJ_DIRECTORY_NAME 8
|
|
||||||
#define GN_OBJ_EDI_PARTY_NAME 10
|
|
||||||
#define GN_OBJ_URI 12
|
|
||||||
#define GN_OBJ_IP_ADDRESS 14
|
|
||||||
#define GN_OBJ_REGISTERED_ID 16
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ASN.1 definition of otherName
|
|
||||||
*/
|
|
||||||
static const asn1Object_t otherNameObjects[] = {
|
|
||||||
{0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
|
|
||||||
{0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
|
|
||||||
{0, "exit", ASN1_EOC, ASN1_EXIT }
|
|
||||||
};
|
|
||||||
#define ON_OBJ_ID_TYPE 0
|
|
||||||
#define ON_OBJ_VALUE 1
|
|
||||||
|
|
||||||
const x509cert_t empty_x509cert = {
|
const x509cert_t empty_x509cert = {
|
||||||
NULL , /* cert */
|
NULL , /* cert */
|
||||||
NULL , /* *next */
|
NULL , /* *next */
|
||||||
@@ -917,23 +861,6 @@ x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *ch
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Free the dynamic memory used to store generalNames
|
|
||||||
*/
|
|
||||||
void free_generalNames(generalName_t* gn, bool free_name)
|
|
||||||
{
|
|
||||||
while (gn)
|
|
||||||
{
|
|
||||||
generalName_t *gn_top = gn;
|
|
||||||
if (free_name)
|
|
||||||
{
|
|
||||||
free(gn->name.ptr);
|
|
||||||
}
|
|
||||||
gn = gn->next;
|
|
||||||
free(gn_top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a X.509 certificate
|
* Free a X.509 certificate
|
||||||
*/
|
*/
|
||||||
@@ -1098,206 +1025,6 @@ chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
|
|||||||
: asn1_wrap(ASN1_OCTET_STRING, "m", signature);
|
: asn1_wrap(ASN1_OCTET_STRING, "m", signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts an otherName
|
|
||||||
*/
|
|
||||||
static bool parse_otherName(chunk_t blob, int level0)
|
|
||||||
{
|
|
||||||
asn1_parser_t *parser;
|
|
||||||
chunk_t object;
|
|
||||||
int objectID;
|
|
||||||
int oid = OID_UNKNOWN;
|
|
||||||
bool success = FALSE;
|
|
||||||
|
|
||||||
parser = asn1_parser_create(otherNameObjects, blob);
|
|
||||||
parser->set_top_level(parser, level0);
|
|
||||||
|
|
||||||
while (parser->iterate(parser, &objectID, &object))
|
|
||||||
{
|
|
||||||
switch (objectID)
|
|
||||||
{
|
|
||||||
case ON_OBJ_ID_TYPE:
|
|
||||||
oid = asn1_known_oid(object);
|
|
||||||
break;
|
|
||||||
case ON_OBJ_VALUE:
|
|
||||||
if (oid == OID_XMPP_ADDR)
|
|
||||||
{
|
|
||||||
if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
|
|
||||||
parser->get_level(parser) + 1, "xmppAddr"))
|
|
||||||
{
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
success = parser->success(parser);
|
|
||||||
|
|
||||||
end:
|
|
||||||
parser->destroy(parser);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts a generalName
|
|
||||||
*/
|
|
||||||
static generalName_t* parse_generalName(chunk_t blob, int level0)
|
|
||||||
{
|
|
||||||
u_char buf[BUF_LEN];
|
|
||||||
asn1_parser_t *parser;
|
|
||||||
chunk_t object;
|
|
||||||
generalName_t *gn = NULL;
|
|
||||||
int objectID;
|
|
||||||
|
|
||||||
parser = asn1_parser_create(generalNameObjects, blob);
|
|
||||||
parser->set_top_level(parser, level0);
|
|
||||||
|
|
||||||
while (parser->iterate(parser, &objectID, &object))
|
|
||||||
{
|
|
||||||
bool valid_gn = FALSE;
|
|
||||||
|
|
||||||
switch (objectID) {
|
|
||||||
case GN_OBJ_RFC822_NAME:
|
|
||||||
case GN_OBJ_DNS_NAME:
|
|
||||||
case GN_OBJ_URI:
|
|
||||||
DBG(DBG_PARSING,
|
|
||||||
DBG_log(" '%.*s'", (int)object.len, object.ptr);
|
|
||||||
)
|
|
||||||
valid_gn = TRUE;
|
|
||||||
break;
|
|
||||||
case GN_OBJ_DIRECTORY_NAME:
|
|
||||||
DBG(DBG_PARSING,
|
|
||||||
dntoa(buf, BUF_LEN, object);
|
|
||||||
DBG_log(" '%s'", buf)
|
|
||||||
)
|
|
||||||
valid_gn = TRUE;
|
|
||||||
break;
|
|
||||||
case GN_OBJ_IP_ADDRESS:
|
|
||||||
DBG(DBG_PARSING,
|
|
||||||
DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
|
|
||||||
*(object.ptr+2), *(object.ptr+3));
|
|
||||||
)
|
|
||||||
valid_gn = TRUE;
|
|
||||||
break;
|
|
||||||
case GN_OBJ_OTHER_NAME:
|
|
||||||
if (!parse_otherName(object, parser->get_level(parser)+1))
|
|
||||||
{
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GN_OBJ_X400_ADDRESS:
|
|
||||||
case GN_OBJ_EDI_PARTY_NAME:
|
|
||||||
case GN_OBJ_REGISTERED_ID:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_gn)
|
|
||||||
{
|
|
||||||
gn = malloc_thing(generalName_t);
|
|
||||||
gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
|
|
||||||
gn->name = object;
|
|
||||||
gn->next = NULL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
parser->destroy(parser);
|
|
||||||
return gn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts one or several GNs and puts them into a chained list
|
|
||||||
*/
|
|
||||||
static generalName_t* parse_generalNames(chunk_t blob, int level0, bool implicit)
|
|
||||||
{
|
|
||||||
asn1_parser_t *parser;
|
|
||||||
chunk_t object;
|
|
||||||
int objectID;
|
|
||||||
generalName_t *top_gn = NULL;
|
|
||||||
|
|
||||||
parser = asn1_parser_create(generalNamesObjects, blob);
|
|
||||||
parser->set_top_level(parser, level0);
|
|
||||||
parser->set_flags(parser, implicit, FALSE);
|
|
||||||
|
|
||||||
while (parser->iterate(parser, &objectID, &object))
|
|
||||||
{
|
|
||||||
if (objectID == GENERAL_NAMES_GN)
|
|
||||||
{
|
|
||||||
generalName_t *gn = parse_generalName(object,
|
|
||||||
parser->get_level(parser)+1);
|
|
||||||
if (gn)
|
|
||||||
{
|
|
||||||
gn->next = top_gn;
|
|
||||||
top_gn = gn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parser->destroy(parser);
|
|
||||||
|
|
||||||
return top_gn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a directoryName
|
|
||||||
*/
|
|
||||||
chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
|
|
||||||
{
|
|
||||||
chunk_t name = chunk_empty;
|
|
||||||
generalName_t * gn = parse_generalNames(blob, level, implicit);
|
|
||||||
|
|
||||||
if (gn && gn->kind == GN_DIRECTORY_NAME)
|
|
||||||
{
|
|
||||||
name= gn->name;
|
|
||||||
}
|
|
||||||
free_generalNames(gn, FALSE);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts an authoritykeyIdentifier
|
|
||||||
*/
|
|
||||||
void parse_authorityKeyIdentifier(chunk_t blob, int level0,
|
|
||||||
chunk_t *authKeyID,
|
|
||||||
chunk_t *authKeySerialNumber)
|
|
||||||
{
|
|
||||||
asn1_parser_t *parser;
|
|
||||||
chunk_t object;
|
|
||||||
int objectID;
|
|
||||||
|
|
||||||
parser = asn1_parser_create(authKeyIdentifierObjects, blob);
|
|
||||||
parser->set_top_level(parser, level0);
|
|
||||||
|
|
||||||
while (parser->iterate(parser, &objectID, &object))
|
|
||||||
{
|
|
||||||
switch (objectID)
|
|
||||||
{
|
|
||||||
case AUTH_KEY_ID_KEY_ID:
|
|
||||||
*authKeyID = object;
|
|
||||||
break;
|
|
||||||
case AUTH_KEY_ID_CERT_ISSUER:
|
|
||||||
{
|
|
||||||
generalName_t * gn = parse_generalNames(object,
|
|
||||||
parser->get_level(parser) + 1, TRUE);
|
|
||||||
|
|
||||||
free_generalNames(gn, FALSE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AUTH_KEY_ID_CERT_SERIAL:
|
|
||||||
*authKeySerialNumber = object;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parser->destroy(parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies a X.509 certificate
|
* Verifies a X.509 certificate
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -26,30 +26,6 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
|
|
||||||
/* Definition of generalNames kinds */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GN_OTHER_NAME = 0,
|
|
||||||
GN_RFC822_NAME = 1,
|
|
||||||
GN_DNS_NAME = 2,
|
|
||||||
GN_X400_ADDRESS = 3,
|
|
||||||
GN_DIRECTORY_NAME = 4,
|
|
||||||
GN_EDI_PARTY_NAME = 5,
|
|
||||||
GN_URI = 6,
|
|
||||||
GN_IP_ADDRESS = 7,
|
|
||||||
GN_REGISTERED_ID = 8
|
|
||||||
} generalNames_t;
|
|
||||||
|
|
||||||
/* access structure for a GeneralName */
|
|
||||||
|
|
||||||
typedef struct generalName generalName_t;
|
|
||||||
|
|
||||||
struct generalName {
|
|
||||||
generalName_t *next;
|
|
||||||
generalNames_t kind;
|
|
||||||
chunk_t name;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* access structure for an X.509v3 certificate */
|
/* access structure for an X.509v3 certificate */
|
||||||
|
|
||||||
typedef struct x509cert x509cert_t;
|
typedef struct x509cert x509cert_t;
|
||||||
@@ -75,7 +51,6 @@ extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
|
|||||||
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0,
|
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0,
|
||||||
chunk_t *authKeyID,
|
chunk_t *authKeyID,
|
||||||
chunk_t *authKeySerialNumber);
|
chunk_t *authKeySerialNumber);
|
||||||
extern chunk_t get_directoryName(chunk_t blob, int level, bool implicit);
|
|
||||||
extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
|
extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
|
||||||
certificate_t *issuer_cert);
|
certificate_t *issuer_cert);
|
||||||
extern chunk_t x509_build_signature(chunk_t tbs, int algorithm,
|
extern chunk_t x509_build_signature(chunk_t tbs, int algorithm,
|
||||||
@@ -90,6 +65,5 @@ extern void store_x509certs(x509cert_t **firstcert, bool strict);
|
|||||||
extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
|
extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
|
||||||
x509_flag_t flags, bool utc);
|
x509_flag_t flags, bool utc);
|
||||||
extern void list_x509_end_certs(bool utc);
|
extern void list_x509_end_certs(bool utc);
|
||||||
extern void free_generalNames(generalName_t* gn, bool free_name);
|
|
||||||
|
|
||||||
#endif /* _X509_H */
|
#endif /* _X509_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user