aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/crypto/ac.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c
index 3104f9fb7..2a1f8294e 100644
--- a/src/libstrongswan/crypto/ac.c
+++ b/src/libstrongswan/crypto/ac.c
@@ -21,6 +21,8 @@
* for more details.
*/
+#include <debug.h>
+
#include <asn1/asn1.h>
#include <utils/identification.h>
#include <utils/linked_list.h>
@@ -316,10 +318,203 @@ static err_t is_valid(const private_x509ac_t *this, time_t *until)
}
/**
+ * parses a directoryName
+ */
+static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
+{
+ *name = NULL;
+ return FALSE;
+}
+
+/**
+ * parses ietfAttrSyntax
+ */
+static void parse_ietfAttrSyntax(chunk_t blob, int level0, linked_list_t *list)
+{
+ /* TODO */
+}
+
+/**
+ * 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;
+ u_int type = OID_UNKNOWN;
+ u_int extn_oid = OID_UNKNOWN;
+ int objectID = 0;
+
+ 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, FALSE, &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:
+ parse_ietfAttrSyntax(object, level, this->charging);
+ break;
+ case OID_GROUP:
+ parse_ietfAttrSyntax(object, level, this->groups);
+ 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:
+ 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 FALSE;
+}
+
+/**
* Implements x509ac_t.destroy
*/
static void destroy(private_x509ac_t *this)
{
+ DESTROY_IF(this->holderIssuer);
+ DESTROY_IF(this->entityName);
+ DESTROY_IF(this->issuerName);
+ free(this->certificate.ptr);
free(this);
}
@@ -331,6 +526,20 @@ 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;
+
+ /* public functions */
+ this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid;
+ this->public.destroy = (void (*) (x509ac_t*))destroy;
+
+ if (!parse_certificate(chunk, this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
}
/*