public static string Format(byte[] bytes)
        {
            SecurityAssert.NotNull(bytes);
            SecurityAssert.Assert(bytes.Length > 0);

            var oid        = new StringBuilder();
            var firstOctet = bytes[0];
            var index      = 1;

            oid.AppendFormat("{0}.{1}", firstOctet / 40, firstOctet % 40);

            while (index < bytes.Length)
            {
                var value = new BigInteger();

                while (true)
                {
                    var b = bytes[index++];

                    if ((b & 0x80) == 0)
                    {
                        value = value << 7 | b;
                        break;
                    }

                    SecurityAssert.Assert(index < bytes.Length);

                    value = value << 7 | (b & 0x7F);
                }

                oid.AppendFormat(".{0}", value);
            }

            return(oid.ToString());
        }
        public static byte[] GetBytes(string oid)
        {
            SecurityAssert.NotNull(oid);
            SecurityAssert.Assert(oid.Length > 0);

            var parts = oid.Split('.').Select(BigInteger.Parse).ToArray();

            SecurityAssert.Assert(parts.Length >= 2);

            var bytes = new List <byte>();

            SecurityAssert.Assert(parts[0] >= 0 && parts[0] <= 6);
            SecurityAssert.Assert(parts[1] >= 0 && parts[1] < 40);

            var firstByte = parts[0] * 40 + parts[1];

            bytes.Add((byte)firstByte);

            for (var i = 2; i < parts.Length; i++)
            {
                SecurityAssert.Assert(parts[i] >= 0);

                bytes.AddRange(EncodeBase128(parts[i]).Reverse());
            }

            return(bytes.ToArray());
        }
        public PublicKey ReadPublicKey(X509AlgorithmIdentifier algorithm, BitArray bits)
        {
            SecurityAssert.Assert(IsRSAIdentifier(algorithm.Algorithm));
            SecurityAssert.Assert(algorithm.Parameters.Count == 1 && algorithm.Parameters[0] is ASN1Null);

            var data = bits.ToArray();

            ASN1Object asn1;

            using (var ms = new MemoryStream(data))
            {
                asn1 = new DERReader(ms).Read();
            }

            var keySeq = asn1 as ASN1Sequence;

            SecurityAssert.Assert(keySeq != null && keySeq.Count == 2);

            var modulusInt = keySeq !.Elements[0] as ASN1Integer;

            SecurityAssert.NotNull(modulusInt);
            var exponentInt = keySeq !.Elements[1] as ASN1Integer;

            SecurityAssert.NotNull(exponentInt);

            return(new RSAPublicKey(modulusInt !.Value, exponentInt !.Value));
        }
Beispiel #4
0
        public RSAPrivateKey(ASN1Object asn1Key)
        {
            // NOTE: currently only supporting PKCS#1 without optional OtherPrimeInfos

            var keySeq = asn1Key as ASN1Sequence;

            SecurityAssert.NotNull(keySeq);
            SecurityAssert.Assert(keySeq !.Count == 9);

            Modulus = GetInteger(keySeq, 1);
            var publicExponent = GetInteger(keySeq, 2);

            Exponent = GetInteger(keySeq, 3);
            var prime1    = GetInteger(keySeq, 4);
            var prime2    = GetInteger(keySeq, 5);
            var exponent1 = GetInteger(keySeq, 6);
            var exponent2 = GetInteger(keySeq, 7);

            // TODO var coefficent = GetInteger(keySeq, 8);

            SecurityAssert.Assert(Modulus == prime1 * prime2);
            SecurityAssert.Assert(exponent1 == Exponent % (prime1 - 1));
            SecurityAssert.Assert(exponent2 == Exponent % (prime2 - 1));
            // TODO assert Coefficent == ((inverse of q) mod p)

            PublicKey = new RSAPublicKey(Modulus, publicExponent);
        }
Beispiel #5
0
        protected override void Reset()
        {
            SecurityAssert.Assert(IVInitialised);

            _workingIV = new byte[BlockLength];
            Array.Copy(IV, _workingIV, BlockLength);
        }
Beispiel #6
0
        public override void Digest(Span <byte> output)
        {
            SecurityAssert.AssertBuffer(output, HashSize / 8);
            SecurityAssert.Assert(WorkBufferEmpty);

            _y.CopyTo(output);
        }
        public PrivateKey ReadKey(byte[] input)
        {
            // PKCS#8 only

            var asn1 = GetASN1(input);

            SecurityAssert.Assert(asn1.HasValue);

            var seq = asn1.Value as ASN1Sequence;

            SecurityAssert.NotNull(seq);
            SecurityAssert.Assert(seq !.Count == 3);

            var version = seq !.Elements[0] as ASN1Integer;

            SecurityAssert.NotNull(version);
            SecurityAssert.Assert(version !.Value == 0);

            var algorithm = X509AlgorithmIdentifier.FromObject(seq.Elements[1]);

            var keyOctetString = seq !.Elements[2] as ASN1OctetString;

            SecurityAssert.NotNull(keyOctetString);

            var reader = _keyReaderRegistry.Resolve(algorithm.Algorithm);

            return(reader.ReadPrivateKey(algorithm, keyOctetString !.Value));
        }
        public static CertificateMessage Read(byte[] body, Func <byte[], X509Reader> x509ReaderFactory)
        {
            using (var stream = new MemoryStream(body))
            {
                var reader = new EndianBinaryReader(EndianBitConverter.Big, stream);

                var certs = new List <X509Certificate>();

                var length = reader.ReadUInt24();
                while (length > 0)
                {
                    SecurityAssert.Assert(length >= 3);

                    var certLength = reader.ReadUInt24();
                    length -= 3;

                    SecurityAssert.Assert(length >= certLength);
                    length -= certLength;

                    var certBytes = reader.ReadBytes((int)certLength);
                    SecurityAssert.Assert(certBytes.Length == certLength);

                    var cert = x509ReaderFactory(certBytes).ReadCertificate();
                    certs.Add(cert);
                }

                return(new CertificateMessage(certs));
            }
        }
Beispiel #9
0
        public void DecryptBlock(byte[] input, int inputOffset, byte[] output, int outputOffset)
        {
            SecurityAssert.Assert(_keyInitialised);
            SecurityAssert.AssertBuffer(input, inputOffset, BlockLength);
            SecurityAssert.AssertBuffer(output, outputOffset, BlockLength);

            var rounds = KeySize / 4 + 6;

            var state = ToState(input, inputOffset);

            AddRoundKey(state, rounds);

            for (var i = rounds - 1; i > 0; i--)
            {
                InvShiftRows(state);
                InvSubBytes(state);
                AddRoundKey(state, i);
                InvMixColumns(state);
            }

            InvShiftRows(state);
            InvSubBytes(state);
            AddRoundKey(state, 0);

            FromState(state, output, outputOffset);
        }
Beispiel #10
0
        public void EncryptBlock(byte[] input, int inputOffset, byte[] output, int outputOffset)
        {
            SecurityAssert.Assert(_keyInitialised);
            SecurityAssert.AssertBuffer(input, inputOffset, BlockLength);
            SecurityAssert.AssertBuffer(output, outputOffset, BlockLength);

            var rounds = KeySize / 4 + 6;

            var state = ToState(input, inputOffset);

            AddRoundKey(state, 0);

            for (var round = 1; round < rounds; round++)
            {
                SubBytes(state);
                ShiftRows(state);
                MixColumns(state);
                AddRoundKey(state, round);
            }

            SubBytes(state);
            ShiftRows(state);
            AddRoundKey(state, rounds);

            FromState(state, output, outputOffset);
        }
Beispiel #11
0
        public void Decrypt(byte[] input, int inputOffset, byte[] output, int outputOffset, int length)
        {
            SecurityAssert.AssertBuffer(input, inputOffset, length);
            SecurityAssert.NotNull(PrivateKey);

            var k = PrivateKey !.Modulus.GetByteLength();

            SecurityAssert.Assert(k >= 11);
            SecurityAssert.Assert(length == k);

            var c = OS2IP(input, inputOffset, length);
            var m = DecryptPrimative(c, PrivateKey !);

            var em = I2OSP(m, k);

            SecurityAssert.Assert(em[0] == 0 && em[1] == 2);

            var mIdx = 2;

            while (mIdx < k && em[mIdx] != 0)
            {
                mIdx++;
            }

            SecurityAssert.Assert(mIdx - 2 > 8);
            // advance past zero
            mIdx++;

            SecurityAssert.AssertBuffer(output, outputOffset, k - mIdx);
            Array.Copy(em, mIdx, output, outputOffset, k - mIdx);
        }
Beispiel #12
0
        public void Encrypt(byte[] input, int inputOffset, byte[] output, int outputOffset, int length)
        {
            SecurityAssert.AssertBuffer(input, inputOffset, length);
            SecurityAssert.NotNull(PublicKey);

            var k = PublicKey !.Modulus.GetByteLength();

            SecurityAssert.Assert(length <= k - 11);

            var ps = _random.RandomNonZeroBytes(k - length - 3);

            SecurityAssert.Assert(ps.Length >= 8);

            var em = new byte[k];

            em[0] = 0;
            em[1] = 2;
            Array.Copy(ps, 0, em, 2, ps.Length);
            em[ps.Length + 2] = 0;
            Array.Copy(input, inputOffset, em, ps.Length + 3, length);

            var m = OS2IP(em, 0, em.Length);
            var c = EncryptPrimative(m, PublicKey !);

            var result = I2OSP(c, k);

            SecurityAssert.AssertBuffer(output, outputOffset, result.Length);
            Array.Copy(result, 0, output, outputOffset, result.Length);
        }
Beispiel #13
0
        private static void LoadCertificates(CertificateManager certificates)
        {
            var rsaCert = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_rsa.cert"));

            SecurityAssert.Assert(rsaCert.Count == 1);
            certificates.AddCertificate(rsaCert[0].RawData);

            var rsaKey = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_rsa.key"));

            SecurityAssert.Assert(rsaKey.Count == 1);
            certificates.AddPrivateKey(rsaKey[0].RawData);

            var ecCert = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_ec.cert"));

            SecurityAssert.Assert(ecCert.Count == 1);
            certificates.AddCertificate(ecCert[0].RawData);

            var ecKey = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_ec.key"));

            SecurityAssert.Assert(ecKey.Count == 1);
            certificates.AddPrivateKey(ecKey[0].RawData);

            var dhCert = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_dh.cert"));

            SecurityAssert.Assert(dhCert.Count == 1);
            certificates.AddCertificate(dhCert[0].RawData);

            var dhKey = PEMReader.TryConvertFromBase64(File.ReadAllBytes("localhost_dh.key"));

            SecurityAssert.Assert(dhKey.Count == 1);
            certificates.AddPrivateKey(dhKey[0].RawData);
        }
        protected override void Reset()
        {
            SecurityAssert.Assert(IVInitialised);

            _counter = new byte[BlockLength];
            Array.Copy(IV, 0, _counter, 0, BlockLength);
        }
Beispiel #15
0
        public virtual void Update(ReadOnlySpan <byte> input)
        {
            var workBuffer = _workBuffer.AsSpan();

            while (input.Length > 0)
            {
                SecurityAssert.Assert(_workBufferLength < BlockSize / 8);

                var lengthToTake = Math.Min(input.Length, _workBuffer.Length - _workBufferLength);

                var(inputToCopy, inputRemaining) = input.Split(lengthToTake);

                inputToCopy.CopyTo(workBuffer.Slice(_workBufferLength));
                _workBufferLength += lengthToTake;
                input              = inputRemaining;

                MessageSize += lengthToTake * 8;

                SecurityAssert.Assert(_workBufferLength <= BlockSize / 8);

                if (_workBufferLength != BlockSize / 8)
                {
                    continue;
                }

                UpdateBlock(_workBuffer);

                _workBufferLength = 0;
                workBuffer.Fill(0);
            }
        }
Beispiel #16
0
        public Record Read(RecordType type, TLSVersion version, ushort length)
        {
            var cipher = GetCipher();

            cipher.Init(GetParameters(ConnectionDirection.Read));

            var payload   = _connection.Reader.ReadBytes(length);
            var plaintext = new byte[payload.Length];

            cipher.Decrypt(payload, 0, plaintext, 0, payload.Length);

            var macAlgo       = GetMAC(ConnectionDirection.Read);
            var macLength     = macAlgo.HashSize / 8;
            var contentLength = plaintext.Length - macLength;

            SecurityAssert.Assert(contentLength >= 0);

            var mac = new byte[macLength];

            Array.Copy(plaintext, contentLength, mac, 0, macLength);

            var content = new byte[contentLength];

            Array.Copy(plaintext, 0, content, 0, content.Length);

            var seqNum      = _sequenceConfig.GetThenIncrement(ConnectionDirection.Read);
            var computedMac = ComputeMAC(macAlgo, seqNum, type, version, content);

            SecurityAssert.AssertHash(mac, computedMac);

            return(new Record(type, version, content));
        }
Beispiel #17
0
        private FieldValue Invert(FieldValue a)
        {
            SecurityAssert.Assert(a.Value != 0);

            var u = a.Value;
            var v = (BigInteger.One << _m) | _ks.Aggregate(BigInteger.One, (current, k) => current | BigInteger.One << k);

            var g1 = BigInteger.One;
            var g2 = BigInteger.Zero;

            while (u != 1)
            {
                var j = u.GetBitLength() - v.GetBitLength();
                if (j < 0)
                {
                    (u, v)   = (v, u);
                    (g1, g2) = (g2, g1);
                    j        = -j;
                }

                u  ^= v << j;
                g1 ^= g2 << j;
            }

            return(Value(g1));
        }
Beispiel #18
0
        public override void Digest(Span <byte> output)
        {
            SecurityAssert.AssertBuffer(output, HashSize / 8);

            var paddingLength = 64 - MessageSize % BlockSize / 8;

            if (paddingLength <= 8)
            {
                paddingLength += 64;
            }

            var padding = new byte[paddingLength];

            // first bit is 1
            padding[0] = 0x80;

            Array.Copy(EndianBitConverter.Big.GetBytes(MessageSize), 0, padding, paddingLength - 8, 8);

            Update(padding);
            SecurityAssert.Assert(WorkBufferEmpty);

            _complete = true;

            EndianBitConverter.Big.GetBytes(_h0).CopyTo(output);
            EndianBitConverter.Big.GetBytes(_h1).CopyTo(output.Slice(4));
            EndianBitConverter.Big.GetBytes(_h2).CopyTo(output.Slice(8));
            EndianBitConverter.Big.GetBytes(_h3).CopyTo(output.Slice(12));
            EndianBitConverter.Big.GetBytes(_h4).CopyTo(output.Slice(16));
        }
Beispiel #19
0
        private static List <int> SievePrimes(int max)
        {
            SecurityAssert.Assert(max > 1);

            var maxSqrt = (int)Math.Ceiling(Math.Sqrt(max));
            var a       = new BitArray(max + 1, true);

            for (var i = 2; i < maxSqrt; i++)
            {
                if (a[i])
                {
                    var j = i * i;
                    while (j <= max)
                    {
                        a[j] = false;
                        j   += i;
                    }
                }
            }

            var list = new List <int>();

            for (var i = 2; i <= max; i++)
            {
                if (a[i])
                {
                    list.Add(i);
                }
            }

            return(list);
        }
Beispiel #20
0
        public GCMCipher(IBlockCipher cipher)
        {
            SecurityAssert.Assert(cipher.BlockLength == 16);
            SecurityAssert.Assert(cipher.KeySize >= 16);

            _cipher = cipher;
        }
Beispiel #21
0
        public byte[] Take(int maxLength)
        {
            SecurityAssert.Assert(maxLength > 0);

            _read.Wait();

            byte[] result;

            var head = _data.Peek();

            if (maxLength < head.Length - _offset)
            {
                result = new byte[maxLength];
                Array.Copy(head, _offset, result, 0, maxLength);

                _offset += maxLength;
            }
            else
            {
                result = _data.Dequeue();

                _offset = 0;
                _write.Release();
            }


            return(result);
        }
 public CertificateMessage(IReadOnlyCollection <X509Certificate> certificates)
     : base(HandshakeType.Certificate)
 {
     SecurityAssert.NotNull(certificates);
     SecurityAssert.Assert(certificates.Count <= 0xFFFFFF);
     Certificates = certificates;
 }
Beispiel #23
0
        public AlertMessage(AlertLevel level, AlertDescription description)
        {
            SecurityAssert.Assert(level.IsAllowed(description));

            Level       = level;
            Description = description;
        }
Beispiel #24
0
        protected override void UpdateBlock(byte[] buffer)
        {
            SecurityAssert.Assert(!_complete);

            var w = new uint[80];

            for (var i = 0; i < 16; i++)
            {
                w[i] = EndianBitConverter.Big.ToUInt32(buffer, i << 2);
            }
            for (var i = 16; i < 80; i++)
            {
                w[i] = LeftRotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
            }

            var a = _h0;
            var b = _h1;
            var c = _h2;
            var d = _h3;
            var e = _h4;

            for (var i = 0; i < 80; i++)
            {
                uint f, k;
                if (i < 20)
                {
                    f = (b & c) | (~b & d);
                    k = 0x5A827999;
                }
                else if (i < 40)
                {
                    f = b ^ c ^ d;
                    k = 0x6ED9EBA1;
                }
                else if (i < 60)
                {
                    f = (b & c) | (b & d) | (c & d);
                    k = 0x8F1BBCDC;
                }
                else
                {
                    f = b ^ c ^ d;
                    k = 0xCA62C1D6;
                }

                var temp = LeftRotate(a, 5) + f + e + k + w[i];
                e = d;
                d = c;
                c = LeftRotate(b, 30);
                b = a;
                a = temp;
            }

            _h0 += a;
            _h1 += b;
            _h2 += c;
            _h3 += d;
            _h4 += e;
        }
Beispiel #25
0
        private ASN1Boolean ReadBoolean(uint length)
        {
            SecurityAssert.Assert(length == 1);

            var value = _reader.ReadByte();

            return(new ASN1Boolean(value != 0));
        }
Beispiel #26
0
        public static void WriteUInt24(this EndianBinaryWriter writer, uint value)
        {
            SecurityAssert.Assert(value <= 0xFFFFFF);

            var buffer = writer.BitConverter.GetBytes(value);

            writer.Write(buffer, 1, 3);
        }
Beispiel #27
0
        public Char2Field(int m, int[] ks)
        {
            SecurityAssert.Assert(m > 0);
            SecurityAssert.Assert(ks.Length == 1 || ks.Length == 3);

            _m  = m;
            _ks = ks;
        }
        public FinishedMessage(byte[] verifyActual, byte[] verifyExpectedHash) : base(HandshakeType.Finished)
        {
            SecurityAssert.NotNull(verifyActual);
            SecurityAssert.Assert(verifyActual.Length == VerifyDataLength);

            VerifyActual       = verifyActual;
            VerifyExpectedHash = verifyExpectedHash;
        }
        public HelloExtension(ExtensionType type, byte[] data)
        {
            Type = type;

            SecurityAssert.NotNull(data);
            SecurityAssert.Assert(data.Length >= 0 && data.Length <= 0xFFFF);
            Data = data;
        }
Beispiel #30
0
        public bool Verify(byte[] input, byte[] signature, IDigest hash)
        {
            if (_publicKey is null || _domain is null || _nField is null)
            {
                throw new InvalidOperationException("ECDSA not initialised");
            }

            FieldValue r, s;

            using (var buffer = new MemoryStream(signature))
            {
                var reader = new DERReader(buffer);

                var seq = reader.Read() as ASN1Sequence;
                SecurityAssert.NotNull(seq);
                SecurityAssert.Assert(seq !.Count == 2);

                var ri = seq.Elements[0] as ASN1Integer;
                SecurityAssert.NotNull(ri);
                r = _nField.Value(ri !.Value);
                SecurityAssert.Assert(r.Value == ri !.Value);

                var si = seq.Elements[1] as ASN1Integer;
                SecurityAssert.NotNull(si);
                s = _nField.Value(si !.Value);
                SecurityAssert.Assert(s.Value == si !.Value);
            }

            // check QA != O
            // check QA is on curve
            SecurityAssert.Assert(_domain.Curve.IsPointOnCurve(_publicKey));
            // check n*QA = O
            // check r and s are in [1, n-1]

            // e = HASH(input)
            hash.Update(input);
            var e = hash.DigestBuffer();

            // z = the Ln leftmost bits of e, where Ln is the bit length of the group order n.
            var z = ToZ(e, _ln);

            // w = 1/s (mod n)
            var w = _nField.Divide(_nField.Value(1), s);

            // u1 = zw (mod n)
            var u1 = _nField.Multiply(w, z);

            // u2 = rw (mod n)
            var u2 = _nField.Multiply(w, r);

            // (x1, y2) = u1 * G + u2 * QA
            var point = Point.Add(_domain.Curve,
                                  a: Point.Multiply(_domain.Curve, u1, _domain.Generator),
                                  b: Point.Multiply(_domain.Curve, u2, _publicKey)) !;

            // return r == x1 (mod n)
            return(r == point.X);
        }