Esempio n. 1
0
        /// <summary>
        /// Writes the core.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="value">The value.</param>
        protected override void WriteCore(Stream stream, RSAParameters value)
        {
            Requires.NotNull(stream, nameof(stream));

            using var sequence = new MemoryStream();

            if (KeyFormatter.HasPrivateKey(value))
            {
                // Only include the version element if this is a private key.
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, new byte[1]));
            }

            // Take care to always prepend a zero when an integer starts with a leading bit of 1,
            // since the ASN.1 spec is that integers are encoded as two's complement, and these integers
            // are always intended to be interpreted as positive.
            sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.Modulus !)));
            sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.Exponent !)));
            if (KeyFormatter.HasPrivateKey(value))
            {
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.D !)));
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.P !)));
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.Q !)));
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.DP !)));
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.DQ !)));
                sequence.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, PrependLeadingZero(value.InverseQ !)));
            }

            stream.WriteAsn1Element(new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Constructed, Asn.BerTag.Sequence, sequence.ToArray()));
        }
        /// <summary>
        /// Reads a key from the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>
        /// The RSA Parameters of the key.
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// Unexpected format.
        /// or
        /// Unexpected format.
        /// or
        /// Unexpected algorithm.
        /// or
        /// Unexpected format.
        /// </exception>
        protected override RSAParameters ReadCore(Stream stream)
        {
            var sequence = stream.ReadAsn1Elements().First();

            if (sequence.Class != Asn.BerClass.Universal || sequence.PC != Asn.BerPC.Constructed || sequence.Tag != Asn.BerTag.Sequence)
            {
                throw new ArgumentException("Unexpected format.");
            }

            var elements = Asn.ReadAsn1Elements(sequence.Content).ToList();

            if (elements.Count != 2 || elements[0].Class != Asn.BerClass.Universal || elements[0].PC != Asn.BerPC.Constructed || elements[0].Tag != Asn.BerTag.Sequence)
            {
                throw new ArgumentException("Unexpected format.");
            }

            var oid = Asn.ReadAsn1Elements(elements[0].Content).First();

            if (!KeyFormatter.BufferEqual(Pkcs1KeyFormatter.RsaEncryptionObjectIdentifier, oid.Content))
            {
                throw new ArgumentException("Unexpected algorithm.");
            }

            if (elements[1].Class != Asn.BerClass.Universal || elements[1].PC != Asn.BerPC.Primitive || elements[1].Tag != Asn.BerTag.BitString || elements[1].Content[0] != 0)
            {
                throw new ArgumentException("Unexpected format.");
            }

            byte[] rsaPublicKey = TrimLeadingZero(elements[1].Content);
            return(KeyFormatter.PublicKeyFilter(KeyFormatter.Pkcs1.Read(rsaPublicKey)));
        }
        /// <summary>
        /// Reads a key from the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>
        /// The RSA Parameters of the key.
        /// </returns>
        protected override RSAParameters ReadCore(Stream stream)
        {
            var universalConstructedSequence = stream.ReadAsn1Elements().Single();
            var sequence = Asn.ReadAsn1Elements(universalConstructedSequence.Content).ToList();

            KeyFormatter.VerifyFormat(sequence[0].Content.Length == 1 && sequence[0].Content[0] == 0x00, Strings.UnrecognizedVersion);
            Asn.DataElement oid = Asn.ReadAsn1Elements(sequence[1].Content).First();
            KeyFormatter.VerifyFormat(X509SubjectPublicKeyInfoFormatter.BufferEqual(oid.Content, Pkcs1KeyFormatter.RsaEncryptionObjectIdentifier), Strings.UnrecognizedObjectIdentifier);
            return(KeyFormatter.Pkcs1.Read(sequence[2].Content));
        }
Esempio n. 4
0
        /// <summary>
        /// Writes a key to the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="parameters">The RSA parameters of the key.</param>
        protected override void WriteCore(Stream stream, RSAParameters parameters)
        {
            var rootElement = new Asn.DataElement(
                Asn.BerClass.Universal,
                Asn.BerPC.Constructed,
                Asn.BerTag.Sequence,
                new Asn.DataElement( // Version 0
                    Asn.BerClass.Universal,
                    Asn.BerPC.Primitive,
                    Asn.BerTag.Integer,
                    new byte[] { 0x00 }),
                new Asn.DataElement(
                    Asn.BerClass.Universal,
                    Asn.BerPC.Constructed,
                    Asn.BerTag.Sequence,
                    new Asn.DataElement( // privateKeyAlgorithm
                        Asn.BerClass.Universal,
                        Asn.BerPC.Primitive,
                        Asn.BerTag.ObjectIdentifier,
                        Pkcs1KeyFormatter.RsaEncryptionObjectIdentifier),
                    new Asn.DataElement(
                        Asn.BerClass.Universal,
                        Asn.BerPC.Primitive,
                        Asn.BerTag.Null,
                        new byte[0])),
                new Asn.DataElement( // rsaPrivateKey
                    Asn.BerClass.Universal,
                    Asn.BerPC.Primitive,
                    Asn.BerTag.OctetString,
                    KeyFormatter.Pkcs1PrependZeros.Write(parameters, HasPrivateKey(parameters))),
                new Asn.DataElement(
                    Asn.BerClass.ContextSpecific,
                    Asn.BerPC.Constructed,
                    Asn.BerTag.EndOfContent,
                    new Asn.DataElement(
                        Asn.BerClass.Universal,
                        Asn.BerPC.Constructed,
                        Asn.BerTag.Sequence,
                        new Asn.DataElement(
                            Asn.BerClass.Universal,
                            Asn.BerPC.Primitive,
                            Asn.BerTag.ObjectIdentifier,
                            new byte[] { 0x55, 0x1d, 0x0f }),
                        new Asn.DataElement(
                            Asn.BerClass.Universal,
                            Asn.BerPC.Constructed,
                            Asn.BerTag.SetAndSetOf,
                            new Asn.DataElement(
                                Asn.BerClass.Universal,
                                Asn.BerPC.Primitive,
                                Asn.BerTag.BitString,
                                new byte[] { 0x00, 0x10 })))));

            Asn.WriteAsn1Element(stream, rootElement);
        }
        /// <summary>
        /// Writes a key to the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="parameters">The RSA parameters of the key.</param>
        protected override void WriteCore(Stream stream, RSAParameters parameters)
        {
            var version0            = new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.Integer, new byte[] { 0x00 });
            var privateKeyAlgorithm = new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.ObjectIdentifier, RsaEncryptionObjectIdentifier);
            var rsaPrivateKey       = new Asn.DataElement(Asn.BerClass.Universal, Asn.BerPC.Primitive, Asn.BerTag.OctetString, Pkcs1.Write(parameters, HasPrivateKey(parameters)));

            var rootElement = new Asn.DataElement(
                Asn.BerClass.Universal,
                Asn.BerPC.Constructed,
                Asn.BerTag.Sequence,
                version0,
                new Asn.DataElement(
                    Asn.BerClass.Universal,
                    Asn.BerPC.Constructed,
                    Asn.BerTag.Sequence,
                    privateKeyAlgorithm,
                    new Asn.DataElement(
                        Asn.BerClass.Universal,
                        Asn.BerPC.Primitive,
                        Asn.BerTag.Null,
                        Array.Empty <byte>())),
                rsaPrivateKey,
                new Asn.DataElement(
                    Asn.BerClass.ContextSpecific,
                    Asn.BerPC.Constructed,
                    Asn.BerTag.EndOfContent,
                    new Asn.DataElement(
                        Asn.BerClass.Universal,
                        Asn.BerPC.Constructed,
                        Asn.BerTag.Sequence,
                        new Asn.DataElement(
                            Asn.BerClass.Universal,
                            Asn.BerPC.Primitive,
                            Asn.BerTag.ObjectIdentifier,
                            new byte[] { 0x55, 0x1d, 0x0f }),
                        new Asn.DataElement(
                            Asn.BerClass.Universal,
                            Asn.BerPC.Constructed,
                            Asn.BerTag.SetAndSetOf,
                            new Asn.DataElement(
                                Asn.BerClass.Universal,
                                Asn.BerPC.Primitive,
                                Asn.BerTag.BitString,
                                new byte[] { 0x00, 0x10 })))));

            Asn.WriteAsn1Element(stream, rootElement);
        }
Esempio n. 6
0
        /// <summary>
        /// Reads a key from the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>
        /// The RSA Parameters of the key.
        /// </returns>
        protected override RSAParameters ReadCore(Stream stream)
        {
            var keyBlobElement = Asn.ReadAsn1Elements(stream).First();

            KeyFormatter.VerifyFormat(
                keyBlobElement.Class == Asn.BerClass.Universal &&
                keyBlobElement.PC == Asn.BerPC.Constructed &&
                keyBlobElement.Tag == Asn.BerTag.Sequence);

            stream = new MemoryStream(keyBlobElement.Content);
            var sequence = Asn.ReadAsn1Elements(stream).ToList();

            switch (sequence.Count)
            {
            case 2:
                return(new RSAParameters
                {
                    Modulus = sequence[0].Content,
                    Exponent = sequence[1].Content,
                });

            case 9:
                KeyFormatter.VerifyFormat(sequence[0].Content.Length == 1 && sequence[0].Content[0] == 0, "Unsupported version.");
                return(new RSAParameters
                {
                    Modulus = sequence[1].Content,
                    Exponent = sequence[2].Content,
                    D = sequence[3].Content,
                    P = sequence[4].Content,
                    Q = sequence[5].Content,
                    DP = sequence[6].Content,
                    DQ = sequence[7].Content,
                    InverseQ = sequence[8].Content,
                });

            default:
                throw KeyFormatter.FailFormat();
            }
        }
Esempio n. 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DataElement"/> struct.
 /// </summary>
 /// <param name="class">The class.</param>
 /// <param name="pc">The PC.</param>
 /// <param name="tag">The tag.</param>
 /// <param name="nestedElements">The content.</param>
 public DataElement(BerClass @class, BerPC pc, BerTag tag, params DataElement[] nestedElements)
     : this(@class, pc, tag, Asn.WriteAsn1Elements(nestedElements))
 {
 }