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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#5
0
        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);
        }
示例#6
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);
        }
示例#7
0
        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);
        }