/* * Parse PKCS#7 wrapped X.509 certificates */ bool parse_pkcs7_cert(chunk_t blob, x509cert_t **cert) { asn1_ctx_t ctx; chunk_t object; int objectID = 0; asn1_init(&ctx, blob, 0, FALSE, DBG_RAW); while (objectID < PKCS7_INFO_ROOF) { if (!extract_object(contentInfoObjects, &objectID, &object, &ctx)) return FALSE; if (objectID == PKCS7_INFO_TYPE) { if (known_oid(object) != OID_PKCS7_SIGNED_DATA) { log("PKCS#7 content type is not signedData"); return FALSE; } } else if (objectID == PKCS7_INFO_CONTENT) { u_int level = contentInfoObjects[objectID].level + 1; parse_pkcs7_signedData(object, level, cert); } objectID++; } return TRUE; }
/* * parse X.501 attributes */ bool parse_attributes(chunk_t blob, scep_attributes_t *attrs) { asn1_ctx_t ctx; chunk_t object; u_int level; int oid = OID_UNKNOWN; int objectID = 0; asn1_init(&ctx, blob, 0, FALSE, DBG_RAW); DBG(DBG_CONTROL | DBG_PARSING, DBG_log("parsing attributes") ) while (objectID < ATTRIBUTE_OBJ_ROOF) { if (!extract_object(attributesObjects, &objectID , &object, &level, &ctx)) return FALSE; switch (objectID) { case ATTRIBUTE_OBJ_TYPE: oid = known_oid(object); break; case ATTRIBUTE_OBJ_VALUE: if (!extract_attribute(oid, object, level, attrs)) return FALSE; } objectID++; } return TRUE; }
/* * Parses an X.509 attribute certificate */ static bool parse_ac(chunk_t blob, x509acert_t *ac) { asn1_ctx_t ctx; bool critical; chunk_t extnID; chunk_t type; chunk_t object; u_int level; u_int objectID = 0; asn1_init(&ctx, blob, 0, FALSE, DBG_RAW); 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: ac->certificate = object; break; case AC_OBJ_CERTIFICATE_INFO: ac->certificateInfo = object; break; case AC_OBJ_VERSION: ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1; DBG(DBG_PARSING, DBG_log(" v%d", ac->version); ) if (ac->version != 2) { libreswan_log("v%d attribute certificates are not supported" , ac->version); return FALSE; } break; case AC_OBJ_HOLDER_ISSUER: ac->holderIssuer = get_directoryName(object, level, FALSE); break; case AC_OBJ_HOLDER_SERIAL: ac->holderSerial = object; break; case AC_OBJ_ENTITY_NAME: ac->entityName = get_directoryName(object, level, TRUE); break; case AC_OBJ_ISSUER_NAME: ac->issuerName = get_directoryName(object, level, FALSE); break; case AC_OBJ_SIG_ALG: ac->sigAlg = parse_algorithmIdentifier(object, level); break; case AC_OBJ_SERIAL_NUMBER: ac->serialNumber = object; break; case AC_OBJ_NOT_BEFORE: ac->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME); break; case AC_OBJ_NOT_AFTER: ac->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME); break; case AC_OBJ_ATTRIBUTE_TYPE: type = object; break; case AC_OBJ_ATTRIBUTE_VALUE: { u_int type_oid = known_oid(type); switch (type_oid) { case OID_AUTHENTICATION_INFO: DBG(DBG_PARSING, DBG_log(" need to parse authenticationInfo") ) break; case OID_ACCESS_IDENTITY: DBG(DBG_PARSING, DBG_log(" need to parse accessIdentity") ) break; case OID_CHARGING_IDENTITY: ac->charging = parse_ietfAttrSyntax(object, level); break; case OID_GROUP: ac->groups = parse_ietfAttrSyntax(object, level); break; case OID_ROLE: parse_roleSyntax(object, level); break; default: break; } } break; case AC_OBJ_EXTN_ID: extnID = object; break; case AC_OBJ_CRITICAL: critical = object.len && *object.ptr; DBG(DBG_PARSING, DBG_log(" %s",(critical)?"TRUE":"FALSE"); ) break; case AC_OBJ_EXTN_VALUE: { u_int extn_oid = known_oid(extnID); switch (extn_oid) { case OID_CRL_DISTRIBUTION_POINTS: DBG(DBG_PARSING, DBG_log(" need to parse crlDistributionPoints") ) break; case OID_AUTHORITY_KEY_ID: parse_authorityKeyIdentifier(object, level , &ac->authKeyID, &ac->authKeySerialNumber); break; case OID_TARGET_INFORMATION: DBG(DBG_PARSING, DBG_log(" need to parse targetInformation") ) break; case OID_NO_REV_AVAIL: ac->noRevAvail = TRUE; break; default: break; } } break; case AC_OBJ_ALGORITHM: ac->algorithm = parse_algorithmIdentifier(object, level); break; case AC_OBJ_SIGNATURE: ac->signature = object; break; default: break; }