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_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 = {
|
||||
NULL , /* cert */
|
||||
NULL , /* *next */
|
||||
@@ -917,23 +861,6 @@ x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *ch
|
||||
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
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -26,30 +26,6 @@
|
||||
#include "constants.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 */
|
||||
|
||||
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,
|
||||
chunk_t *authKeyID,
|
||||
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,
|
||||
certificate_t *issuer_cert);
|
||||
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,
|
||||
x509_flag_t flags, bool utc);
|
||||
extern void list_x509_end_certs(bool utc);
|
||||
extern void free_generalNames(generalName_t* gn, bool free_name);
|
||||
|
||||
#endif /* _X509_H */
|
||||
|
||||
Reference in New Issue
Block a user