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)); }
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); }
protected override void Reset() { SecurityAssert.Assert(IVInitialised); _workingIV = new byte[BlockLength]; Array.Copy(IV, _workingIV, BlockLength); }
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)); } }
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); }
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); }
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); }
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); }
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); }
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); } }
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)); }
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)); }
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)); }
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); }
public GCMCipher(IBlockCipher cipher) { SecurityAssert.Assert(cipher.BlockLength == 16); SecurityAssert.Assert(cipher.KeySize >= 16); _cipher = cipher; }
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; }
public AlertMessage(AlertLevel level, AlertDescription description) { SecurityAssert.Assert(level.IsAllowed(description)); Level = level; Description = description; }
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; }
private ASN1Boolean ReadBoolean(uint length) { SecurityAssert.Assert(length == 1); var value = _reader.ReadByte(); return(new ASN1Boolean(value != 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); }
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; }
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); }