Exemple #1
0
        private static unsafe int DecodeSubjectPublicKeyInfo(
            ReadOnlySpan <byte> source,
            out Oid oid,
            out AsnEncodedData parameters,
            out AsnEncodedData keyValue)
        {
            fixed(byte *ptr = &MemoryMarshal.GetReference(source))
            using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
            {
                AsnValueReader reader = new AsnValueReader(source, AsnEncodingRules.DER);

                int read;
                SubjectPublicKeyInfoAsn spki;

                try
                {
                    read = reader.PeekEncodedValue().Length;
                    SubjectPublicKeyInfoAsn.Decode(ref reader, manager.Memory, out spki);
                }
                catch (AsnContentException e)
                {
                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
                }

                oid        = new Oid(spki.Algorithm.Algorithm, null);
                parameters = new AsnEncodedData(spki.Algorithm.Parameters?.ToArray() ?? Array.Empty <byte>());
                keyValue   = new AsnEncodedData(spki.SubjectPublicKey.ToArray());
                return(read);
            }
        }
Exemple #2
0
            public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead)
            {
                ThrowIfDisposed();

                fixed(byte *ptr = &MemoryMarshal.GetReference(source))
                {
                    using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                    {
                        AsnReader             reader       = new AsnReader(manager.Memory, AsnEncodingRules.BER);
                        ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue();

                        SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
                        {
                            Algorithm = new AlgorithmIdentifierAsn
                            {
                                Algorithm  = new Oid(Oids.Rsa),
                                Parameters = AlgorithmIdentifierAsn.ExplicitDerNull,
                            },
                            SubjectPublicKey = firstElement,
                        };

                        using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                        {
                            spki.Encode(writer);
                            ImportSubjectPublicKeyInfo(writer.EncodeAsSpan(), out _);
                        }

                        bytesRead = firstElement.Length;
                    }
                }
            }
Exemple #3
0
            private static AsymmetricAlgorithm DecodeDsaPublicKey(byte[] encodedKeyValue, byte[] encodedParameters)
            {
                SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
                {
                    Algorithm = new AlgorithmIdentifierAsn {
                        Algorithm = new Oid(Oids.Dsa, null), Parameters = encodedParameters
                    },
                    SubjectPublicKey = encodedKeyValue,
                };

                using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                {
                    spki.Encode(writer);
                    DSA dsa = DSA.Create();
                    try
                    {
                        dsa.ImportSubjectPublicKeyInfo(writer.EncodeAsSpan(), out _);
                        return(dsa);
                    }
                    catch (Exception)
                    {
                        dsa.Dispose();
                        throw;
                    }
                }
            }
Exemple #4
0
        public virtual byte[] ComputeCapiSha1OfPublicKey(PublicKey key)
        {
            // The CapiSha1 value is the SHA-1 of the SubjectPublicKeyInfo field, inclusive
            // of the DER structural bytes.

            SubjectPublicKeyInfoAsn spki = default;

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = key.Oid !.Value !, Parameters = key.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = key.EncodedKeyValue.RawData;

            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            spki.Encode(writer);

            byte[] rented = CryptoPool.Rent(writer.GetEncodedLength());

            try
            {
                if (!writer.TryEncode(rented, out int bytesWritten))
                {
                    Debug.Fail("TryEncode failed with a pre-allocated buffer");
                    throw new CryptographicException();
                }

                return(SHA1.HashData(rented.AsSpan(0, bytesWritten)));
            }
            finally
            {
                CryptoPool.Return(rented, clearSize: 0); // SubjectPublicKeyInfo is not sensitive.
            }
        }
        private static DSA BuildDsaPublicKey(byte[] encodedKeyValue, byte[] encodedParameters)
        {
            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
            {
                Algorithm = new AlgorithmIdentifierAsn {
                    Algorithm = Oids.Dsa, Parameters = encodedParameters
                },
                SubjectPublicKey = encodedKeyValue,
            };

            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            spki.Encode(writer);

            DSA dsa = new DSAOpenSsl();

            try
            {
                dsa.ImportSubjectPublicKeyInfo(writer.Encode(), out _);
                return(dsa);
            }
            catch (Exception)
            {
                dsa.Dispose();
                throw;
            }
        }
Exemple #6
0
            private static DSA DecodeDsaPublicKey(byte[] encodedKeyValue, byte[] encodedParameters)
            {
                SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
                {
                    Algorithm = new AlgorithmIdentifierAsn {
                        Algorithm = Oids.Dsa, Parameters = encodedParameters
                    },
                    SubjectPublicKey = encodedKeyValue,
                };

                AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

                spki.Encode(writer);

                byte[] rented = CryptoPool.Rent(writer.GetEncodedLength());

                int written = writer.Encode(rented);

                DSA         dsa       = DSA.Create();
                IDisposable?toDispose = dsa;

                try
                {
                    dsa.ImportSubjectPublicKeyInfo(rented.AsSpan(0, written), out _);
                    toDispose = null;
                    return(dsa);
                }
                finally
                {
                    toDispose?.Dispose();
                    CryptoPool.Return(rented, written);
                }
            }
Exemple #7
0
        internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            // State validation should be runtime checks if/when this becomes public API
            Debug.Assert(signatureGenerator != null);
            Debug.Assert(Subject != null);
            Debug.Assert(PublicKey != null);

            byte[] signatureAlgorithm = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm);
            AlgorithmIdentifierAsn signatureAlgorithmAsn;

            // Deserialization also does validation of the value (except for Parameters, which have to be validated separately).
            signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER);
            if (signatureAlgorithmAsn.Parameters.HasValue)
            {
                Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value.Span);
            }

            SubjectPublicKeyInfoAsn spki = default;

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = PublicKey.Oid !.Value !, Parameters = PublicKey.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = PublicKey.EncodedKeyValue.RawData;

            var attributes = new AttributeAsn[Attributes.Count];

            for (int i = 0; i < attributes.Length; i++)
            {
                attributes[i] = new AttributeAsn(Attributes[i]);
            }

            CertificationRequestInfoAsn requestInfo = new CertificationRequestInfoAsn
            {
                Version = 0,
                Subject = this.Subject.RawData,
                SubjectPublicKeyInfo = spki,
                Attributes           = attributes
            };

            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            requestInfo.Encode(writer);
            byte[] encodedRequestInfo = writer.Encode();
            writer.Reset();

            CertificationRequestAsn certificationRequest = new CertificationRequestAsn
            {
                CertificationRequestInfo = requestInfo,
                SignatureAlgorithm       = signatureAlgorithmAsn,
                SignatureValue           = signatureGenerator.SignData(encodedRequestInfo, hashAlgorithm),
            };

            certificationRequest.Encode(writer);
            return(writer.Encode());
        }
    }
Exemple #8
0
 private static void DecodeSubjectPublicKeyInfo(
     ref SubjectPublicKeyInfoAsn spki,
     out Oid oid,
     out AsnEncodedData parameters,
     out AsnEncodedData keyValue)
 {
     oid        = new Oid(spki.Algorithm.Algorithm, null);
     parameters = new AsnEncodedData(spki.Algorithm.Parameters.GetValueOrDefault().Span);
     keyValue   = new AsnEncodedData(spki.SubjectPublicKey.Span);
 }
Exemple #9
0
        internal static PublicKey DecodeSubjectPublicKeyInfo(ref SubjectPublicKeyInfoAsn spki)
        {
            DecodeSubjectPublicKeyInfo(
                ref spki,
                out Oid oid,
                out AsnEncodedData parameters,
                out AsnEncodedData keyValue);

            return(new PublicKey(oid, parameters, keyValue));
        }
Exemple #10
0
        internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
        {
            // State validation should be runtime checks if/when this becomes public API
            Debug.Assert(signatureGenerator != null);
            Debug.Assert(Subject != null);
            Debug.Assert(PublicKey != null);

            byte[] signatureAlgorithm = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm);
            AlgorithmIdentifierAsn signatureAlgorithmAsn;

            // Deserialization also does validation of the value (except for Parameters, which have to be validated separately).
            signatureAlgorithmAsn = AlgorithmIdentifierAsn.Decode(signatureAlgorithm, AsnEncodingRules.DER);
            if (signatureAlgorithmAsn.Parameters.HasValue)
            {
                Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value);
            }

            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn();

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = PublicKey.Oid, Parameters = PublicKey.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = PublicKey.EncodedKeyValue.RawData;

            CertificationRequestInfoAsn requestInfo = new CertificationRequestInfoAsn
            {
                Version = 0,
                Subject = this.Subject.RawData,
                SubjectPublicKeyInfo = spki,
                Attributes           = Attributes.Select(a => new AttributeAsn(a)).ToArray(),
            };

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
                using (AsnWriter signedWriter = new AsnWriter(AsnEncodingRules.DER))
                {
                    requestInfo.Encode(writer);

                    byte[] encodedRequestInfo = writer.Encode();
                    CertificationRequestAsn certificationRequest = new CertificationRequestAsn
                    {
                        CertificationRequestInfo = requestInfo,
                        SignatureAlgorithm       = signatureAlgorithmAsn,
                        SignatureValue           = signatureGenerator.SignData(encodedRequestInfo, hashAlgorithm),
                    };

                    certificationRequest.Encode(signedWriter);
                    return(signedWriter.Encode());
                }
        }
Exemple #11
0
            public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead)
            {
                ThrowIfDisposed();

                fixed(byte *ptr = &MemoryMarshal.GetReference(source))
                {
                    using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length))
                    {
                        ReadOnlyMemory <byte> subjectPublicKey;
                        try
                        {
                            AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER);
                            subjectPublicKey = reader.PeekEncodedValue();
                        }
                        catch (AsnContentException e)
                        {
                            throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
                        }

                        // Decoding the key on Android requires the encoded SubjectPublicKeyInfo,
                        // not just the SubjectPublicKey, so we construct one.
                        SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
                        {
                            Algorithm = new AlgorithmIdentifierAsn
                            {
                                Algorithm  = Oids.Rsa,
                                Parameters = AlgorithmIdentifierAsn.ExplicitDerNull,
                            },
                            SubjectPublicKey = subjectPublicKey,
                        };

                        AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);
                        spki.Encode(writer);

                        SafeRsaHandle key = Interop.AndroidCrypto.DecodeRsaSubjectPublicKeyInfo(writer.Encode());
                        if (key is null || key.IsInvalid)
                        {
                            key?.Dispose();
                            throw new CryptographicException();
                        }

                        FreeKey();
                        _key = new Lazy <SafeRsaHandle>(key);
                        SetKeySizeFromHandle(key);

                        bytesRead = subjectPublicKey.Length;
                    }
                }
            }
Exemple #12
0
        private AsnWriter EncodeSubjectPublicKeyInfo()
        {
            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
            {
                Algorithm = new AlgorithmIdentifierAsn
                {
                    Algorithm  = _oid.Value ?? string.Empty,
                    Parameters = EncodedParameters.RawData,
                },
                SubjectPublicKey = EncodedKeyValue.RawData,
            };

            AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

            spki.Encode(writer);
            return(writer);
        }
        private static DSA BuildDsaPublicKey(byte[] encodedKey, byte[] encodedParameters)
        {
            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
            {
                Algorithm = new AlgorithmIdentifierAsn {
                    Algorithm = new Oid(Oids.Dsa), Parameters = encodedParameters
                },
                SubjectPublicKey = encodedKey,
            };

            using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER))
            {
                DSA dsa = new DSAOpenSsl();
                spki.Encode(writer);
                dsa.ImportSubjectPublicKeyInfo(writer.EncodeAsSpan(), out _);
                return(dsa);
            }
        }
        public virtual byte[] ComputeCapiSha1OfPublicKey(PublicKey key)
        {
            // The CapiSha1 value is the SHA-1 of the SubjectPublicKeyInfo field, inclusive
            // of the DER structural bytes.

            SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn();

            spki.Algorithm = new AlgorithmIdentifierAsn {
                Algorithm = key.Oid, Parameters = key.EncodedParameters.RawData
            };
            spki.SubjectPublicKey = key.EncodedKeyValue.RawData;

            using (AsnWriter writer = AsnSerializer.Serialize(spki, AsnEncodingRules.DER))
                using (SHA1 hash = SHA1.Create())
                {
                    return(hash.ComputeHash(writer.Encode()));
                }
        }
Exemple #15
0
            private static AsymmetricAlgorithm DecodeDsaPublicKey(byte[] encodedKeyValue, byte[] encodedParameters)
            {
                SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn
                {
                    Algorithm = new AlgorithmIdentifierAsn {
                        Algorithm = Oids.Dsa, Parameters = encodedParameters
                    },
                    SubjectPublicKey = encodedKeyValue,
                };

                AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

                spki.Encode(writer);

                byte[] rented = CryptoPool.Rent(writer.GetEncodedLength());

                if (!writer.TryEncode(rented, out int written))
                {
                    Debug.Fail("TryEncode failed with a pre-allocated buffer");
                    throw new InvalidOperationException();
                }

                DSA         dsa       = DSA.Create();
                IDisposable?toDispose = dsa;

                try
                {
                    dsa.ImportSubjectPublicKeyInfo(rented.AsSpan(0, written), out _);
                    toDispose = null;
                    return(dsa);
                }
                finally
                {
                    toDispose?.Dispose();
                    CryptoPool.Return(rented, written);
                }
            }