internal static byte U2FTransportsFromAttnCert(X509ExtensionCollection exts) { var u2ftransports = new byte(); var ext = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid.Value is "1.3.6.1.4.1.45724.2.1.1"); if (ext != null) { var decodedU2Ftransports = Asn1Element.Decode(ext.RawData); decodedU2Ftransports.CheckPrimitive(); // some certificates seem to have this encoded as an octet string // instead of a bit string, attempt to correct if (decodedU2Ftransports.Tag == Asn1Tag.PrimitiveOctetString) { ext.RawData[0] = (byte)UniversalTagNumber.BitString; decodedU2Ftransports = Asn1Element.Decode(ext.RawData); } decodedU2Ftransports.CheckTag(Asn1Tag.PrimitiveBitString); u2ftransports = decodedU2Ftransports.GetBitString()[0]; } return(u2ftransports); }
public static byte[] GetAppleAttestationExtensionValue(X509ExtensionCollection exts) { var appleExtension = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid !.Value is "1.2.840.113635.100.8.2"); if (appleExtension is null || appleExtension.RawData is null || appleExtension.RawData.Length < 0x26) { throw new Fido2VerificationException("Extension with OID 1.2.840.113635.100.8.2 not found on Apple attestation credCert"); } try { var appleAttestationASN = Asn1Element.Decode(appleExtension.RawData); appleAttestationASN.CheckTag(new Asn1Tag(UniversalTagNumber.Sequence, isConstructed: true)); appleAttestationASN.CheckExactSequenceLength(1); var appleAttestationASNSequence = appleAttestationASN[0]; appleAttestationASNSequence.CheckConstructed(); appleAttestationASNSequence.CheckExactSequenceLength(1); appleAttestationASNSequence[0].CheckTag(Asn1Tag.PrimitiveOctetString); return(appleAttestationASNSequence[0].GetOctetString()); } catch (Exception ex) { throw new Fido2VerificationException("Apple attestation extension has invalid data", ex); } }
public static byte[] GetAttestationChallenge(byte[] attExtBytes) { // https://developer.android.com/training/articles/security-key-attestation#certificate_schema // attestationChallenge at index 4 var keyDescription = Asn1Element.Decode(attExtBytes); return(keyDescription[4].GetOctetString()); }
internal static byte[] AaguidFromAttnCertExts(X509ExtensionCollection exts) { byte[] aaguid = null; var ext = exts.Cast <X509Extension>().FirstOrDefault(e => e.Oid.Value is "1.3.6.1.4.1.45724.1.1.4"); // id-fido-gen-ce-aaguid if (ext != null) { var decodedAaguid = Asn1Element.Decode(ext.RawData); decodedAaguid.CheckTag(Asn1Tag.PrimitiveOctetString); aaguid = decodedAaguid.GetOctetString(); // The extension MUST NOT be marked as critical if (ext.Critical) { throw new Fido2VerificationException("extension MUST NOT be marked as critical"); } } return(aaguid); }
public static bool IsOriginGenerated(byte[] attExtBytes) { int softwareEnforcedOriginValue = 0; int teeEnforcedOriginValue = 0; // https://developer.android.com/training/articles/security-key-attestation#certificate_schema // origin tag is 702 var keyDescription = Asn1Element.Decode(attExtBytes); var softwareEnforced = keyDescription[6].Sequence; foreach (Asn1Element s in softwareEnforced) { switch (s.TagValue) { case 702: softwareEnforcedOriginValue = s[0].GetInt32(); break; default: break; } } var teeEnforced = keyDescription[7].Sequence; foreach (Asn1Element s in teeEnforced) { switch (s.TagValue) { case 702: teeEnforcedOriginValue = s[0].GetInt32(); break; default: break; } } return(softwareEnforcedOriginValue is 0 && teeEnforcedOriginValue is 0); }
public static bool IsPurposeSign(byte[] attExtBytes) { int softwareEnforcedPurposeValue = 2; int teeEnforcedPurposeValue = 2; // https://developer.android.com/training/articles/security-key-attestation#certificate_schema // purpose tag is 1 var keyDescription = Asn1Element.Decode(attExtBytes); var softwareEnforced = keyDescription[6].Sequence; foreach (Asn1Element s in softwareEnforced) { switch (s.TagValue) { case 1: softwareEnforcedPurposeValue = s[0][0].GetInt32(); break; default: break; } } var teeEnforced = keyDescription[7].Sequence; foreach (Asn1Element s in teeEnforced) { switch (s.TagValue) { case 1: teeEnforcedPurposeValue = s[0][0].GetInt32(); break; default: break; } } return(softwareEnforcedPurposeValue is 2 && teeEnforcedPurposeValue is 2); }
public static bool FindAllApplicationsField(byte[] attExtBytes) { // https://developer.android.com/training/articles/security-key-attestation#certificate_schema // check both software and tee enforced AuthorizationList objects for presense of "allApplications" tag, number 600 var keyDescription = Asn1Element.Decode(attExtBytes); var softwareEnforced = keyDescription[6].Sequence; foreach (Asn1Element s in softwareEnforced) { switch (s.TagValue) { case 600: return(true); default: break; } } var teeEnforced = keyDescription[7].Sequence; foreach (Asn1Element s in teeEnforced) { switch (s.TagValue) { case 600: return(true); default: break; } } return(false); }