예제 #1
0
        protected void ParsePkcs12(ReadOnlySpan <byte> data)
        {
            try
            {
                // RFC7292 specifies BER instead of DER
                AsnValueReader reader = new AsnValueReader(data, AsnEncodingRules.BER);

                // Windows compatibility: Ignore trailing data.
                ReadOnlySpan <byte> encodedData = reader.PeekEncodedValue();

                unsafe
                {
                    IntPtr      tmpPtr  = Marshal.AllocHGlobal(encodedData.Length);
                    Span <byte> tmpSpan = new Span <byte>((byte *)tmpPtr, encodedData.Length);
                    encodedData.CopyTo(tmpSpan);
                    _tmpManager = new PointerMemoryManager <byte>((void *)tmpPtr, encodedData.Length);
                }

                ReadOnlyMemory <byte> tmpMemory = _tmpManager.Memory;
                reader = new AsnValueReader(tmpMemory.Span, AsnEncodingRules.BER);

                PfxAsn.Decode(ref reader, tmpMemory, out PfxAsn pfxAsn);

                if (pfxAsn.AuthSafe.ContentType != Oids.Pkcs7Data)
                {
                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                }

                _pfxAsn = pfxAsn;
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
예제 #2
0
            public X509ContentType GetCertContentType(byte[] rawData)
            {
                const int errSecUnknownFormat = -25257;

                if (rawData == null || rawData.Length == 0)
                {
                    // Throw to match Windows and Unix behavior.
                    throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnknownFormat);
                }

                X509ContentType contentType = Interop.AppleCrypto.X509GetContentType(rawData, rawData.Length);

                // Apple doesn't seem to recognize PFX files with no MAC, so try a quick maybe-it's-a-PFX test
                if (contentType == X509ContentType.Unknown)
                {
                    try
                    {
                        PfxAsn.Decode(rawData, AsnEncodingRules.BER);
                        contentType = X509ContentType.Pkcs12;
                    }
                    catch (CryptographicException)
                    {
                    }
                }

                if (contentType == X509ContentType.Unknown)
                {
                    // Throw to match Windows and Unix behavior.
                    throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnknownFormat);
                }

                return(contentType);
            }
예제 #3
0
        protected void ParsePkcs12(byte[] data)
        {
            try
            {
                // RFC7292 specifies BER instead of DER
                AsnValueReader      reader      = new AsnValueReader(data, AsnEncodingRules.BER);
                ReadOnlySpan <byte> encodedData = reader.PeekEncodedValue();

                // Windows compatibility: Ignore trailing data.
                if (encodedData.Length != data.Length)
                {
                    reader = new AsnValueReader(encodedData, AsnEncodingRules.BER);
                }

                PfxAsn.Decode(ref reader, data, out PfxAsn pfxAsn);

                if (pfxAsn.AuthSafe.ContentType != Oids.Pkcs7Data)
                {
                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                }

                _pfxAsn = pfxAsn;
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }
예제 #4
0
            public X509ContentType GetCertContentType(ReadOnlySpan <byte> rawData)
            {
                const int errSecUnknownFormat = -25257;

                if (rawData == null || rawData.Length == 0)
                {
                    // Throw to match Windows and Unix behavior.
                    throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnknownFormat);
                }

                X509ContentType contentType = Interop.AppleCrypto.X509GetContentType(rawData);

                // Apple doesn't seem to recognize PFX files with no MAC, so try a quick maybe-it's-a-PFX test
                if (contentType == X509ContentType.Unknown)
                {
                    try
                    {
                        unsafe
                        {
                            fixed(byte *pin = rawData)
                            {
                                using (var manager = new PointerMemoryManager <byte>(pin, rawData.Length))
                                {
                                    PfxAsn.Decode(manager.Memory, AsnEncodingRules.BER);
                                }

                                contentType = X509ContentType.Pkcs12;
                            }
                        }
                    }
                    catch (CryptographicException)
                    {
                    }
                }

                if (contentType == X509ContentType.Unknown)
                {
                    // Throw to match Windows and Unix behavior.
                    throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnknownFormat);
                }

                return(contentType);
            }
예제 #5
0
        private static bool IsPkcs12(ReadOnlySpan <byte> rawData)
        {
            try
            {
                unsafe
                {
                    fixed(byte *pin = rawData)
                    {
                        using (var manager = new PointerMemoryManager <byte>(pin, rawData.Length))
                        {
                            PfxAsn.Decode(manager.Memory, AsnEncodingRules.BER);
                        }

                        return(true);
                    }
                }
            }
            catch (CryptographicException)
            {
            }

            return(false);
        }
예제 #6
0
        public static Pkcs12Info Decode(
            ReadOnlyMemory <byte> encodedBytes,
            out int bytesConsumed,
            bool skipCopy = false)
        {
            AsnReader reader = new AsnReader(encodedBytes, AsnEncodingRules.BER);

            // Trim it to the first value
            encodedBytes = reader.PeekEncodedValue();

            ReadOnlyMemory <byte> maybeCopy = skipCopy ? encodedBytes : encodedBytes.ToArray();
            PfxAsn pfx = PfxAsn.Decode(maybeCopy, AsnEncodingRules.BER);

            // https://tools.ietf.org/html/rfc7292#section-4 only defines version 3.
            if (pfx.Version != 3)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            ReadOnlyMemory <byte> authSafeBytes = ReadOnlyMemory <byte> .Empty;
            Pkcs12IntegrityMode   mode          = Pkcs12IntegrityMode.Unknown;

            if (pfx.AuthSafe.ContentType == Oids.Pkcs7Data)
            {
                authSafeBytes = PkcsHelpers.DecodeOctetStringAsMemory(pfx.AuthSafe.Content);

                if (pfx.MacData.HasValue)
                {
                    mode = Pkcs12IntegrityMode.Password;
                }
                else
                {
                    mode = Pkcs12IntegrityMode.None;
                }
            }
            else if (pfx.AuthSafe.ContentType == Oids.Pkcs7Signed)
            {
                SignedDataAsn signedData = SignedDataAsn.Decode(pfx.AuthSafe.Content, AsnEncodingRules.BER);

                mode = Pkcs12IntegrityMode.PublicKey;

                if (signedData.EncapContentInfo.ContentType == Oids.Pkcs7Data)
                {
                    authSafeBytes = signedData.EncapContentInfo.Content.GetValueOrDefault();
                }

                if (pfx.MacData.HasValue)
                {
                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
                }
            }

            if (mode == Pkcs12IntegrityMode.Unknown)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
            }

            List <ContentInfoAsn> authSafeData   = new List <ContentInfoAsn>();
            AsnReader             authSafeReader = new AsnReader(authSafeBytes, AsnEncodingRules.BER);
            AsnReader             sequenceReader = authSafeReader.ReadSequence();

            authSafeReader.ThrowIfNotEmpty();
            while (sequenceReader.HasData)
            {
                ContentInfoAsn.Decode(sequenceReader, out ContentInfoAsn contentInfo);
                authSafeData.Add(contentInfo);
            }

            ReadOnlyCollection <Pkcs12SafeContents> authSafe;

            if (authSafeData.Count == 0)
            {
                authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(Array.Empty <Pkcs12SafeContents>());
            }
            else
            {
                Pkcs12SafeContents[] contentsArray = new Pkcs12SafeContents[authSafeData.Count];

                for (int i = 0; i < contentsArray.Length; i++)
                {
                    contentsArray[i] = new Pkcs12SafeContents(authSafeData[i]);
                }

                authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(contentsArray);
            }

            bytesConsumed = encodedBytes.Length;

            return(new Pkcs12Info
            {
                AuthenticatedSafe = authSafe,
                IntegrityMode = mode,
                _decoded = pfx,
                _authSafeContents = authSafeBytes,
            });
        }