/// <summary> /// Calls HMAC() /// </summary> /// <param name="digest"></param> /// <param name="key"></param> /// <param name="data"></param> /// <returns></returns> public static byte[] Digest(MessageDigest digest, byte[] key, byte[] data) { var hash_value = new byte[digest.Size]; uint hash_value_length = Native.EVP_MAX_MD_SIZE; Native.HMAC(digest.Handle, key, key.Length, data, data.Length, hash_value, ref hash_value_length); return hash_value; }
/// <summary> /// Calls EVP_VerifyFinal() /// </summary> /// <param name="md"></param> /// <param name="bio"></param> /// <param name="sig"></param> /// <param name="pkey"></param> /// <returns></returns> public static bool Verify(MessageDigest md, BIO bio, byte[] sig, CryptoKey pkey) { BIO bmd = BIO.MessageDigest(md); bmd.Push(bio); while (true) { ArraySegment <byte> bytes = bmd.ReadBytes(1024 * 4); if (bytes.Count == 0) { break; } } MessageDigestContext ctx = new MessageDigestContext(bmd); int ret = Native.ExpectSuccess(Native.EVP_VerifyFinal(ctx.Handle, sig, (uint)sig.Length, pkey.Handle)); return(ret == 1); }
/// <summary> /// Calls EVP_BytesToKey /// </summary> /// <param name="md"></param> /// <param name="salt"></param> /// <param name="data"></param> /// <param name="count"></param> /// <param name="iv"></param> /// <returns></returns> public byte[] BytesToKey(MessageDigest md, byte[] salt, byte[] data, int count, out byte[] iv) { byte[] key = new byte[this.cipher.KeyLength]; iv = new byte[this.cipher.IVLength]; Native.ExpectSuccess(Native.EVP_BytesToKey( this.cipher.Handle, md.Handle, salt, data, data.Length, count, key, iv)); return key; }
/// <summary> /// Process an X509Request. This includes creating a new X509Certificate /// and signing this certificate with this CA's private key. /// </summary> /// <param name="request"></param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="cfg"></param> /// <param name="section"></param> /// <param name="digest"></param> /// <returns></returns> public X509Certificate ProcessRequest( X509Request request, DateTime startTime, DateTime endTime, Configuration cfg, string section, MessageDigest digest) { // using (var pkey = request.PublicKey) // { // if (!request.Verify(pkey)) // throw new Exception("Request signature validation failed"); // } var cert = new X509Certificate( serial.Next(), request.Subject, this.caCert.Subject, request.PublicKey, startTime, endTime); if (cfg != null) cfg.ApplyExtensions(section, caCert, cert, request); cert.Sign(caKey, digest); return cert; }
/// <summary> /// Factory method that creates a X509CertificateAuthority instance with /// an internal self signed certificate. This method allows creation without /// the need for the Configuration file, X509V3Extensions may be added /// with the X509V3ExtensionList parameter /// </summary> /// <param name="seq"></param> /// <param name="key"></param> /// <param name="digest"></param> /// <param name="subject"></param> /// <param name="start"></param> /// <param name="validity"></param> /// <param name="extensions"></param> /// <returns></returns> public static X509CertificateAuthority SelfSigned( ISequenceNumber seq, CryptoKey key, MessageDigest digest, X509Name subject, DateTime start, TimeSpan validity, IEnumerable<X509V3ExtensionValue> extensions) { var cert = new X509Certificate( seq.Next(), subject, subject, key, start, start + validity); if (extensions != null) { foreach (var extValue in extensions) { using (var ext = new X509Extension(cert, cert, extValue.Name, extValue.IsCritical, extValue.Value)) { cert.AddExtension(ext); } } } cert.Sign(key, digest); return new X509CertificateAuthority(cert, key, seq); }
/// <summary> /// Factory method that creates a X509CertificateAuthority instance with /// an internal self signed certificate /// </summary> /// <param name="cfg"></param> /// <param name="seq"></param> /// <param name="key"></param> /// <param name="digest"></param> /// <param name="subject"></param> /// <param name="start"></param> /// <param name="validity"></param> /// <returns></returns> public static X509CertificateAuthority SelfSigned( Configuration cfg, ISequenceNumber seq, CryptoKey key, MessageDigest digest, X509Name subject, DateTime start, TimeSpan validity) { var cert = new X509Certificate( seq.Next(), subject, subject, key, start, start + validity); if (cfg != null) cfg.ApplyExtensions("v3_ca", cert, cert, null); cert.Sign(key, digest); return new X509CertificateAuthority(cert, key, seq); }
/// <summary> /// Calls HMAC_Init_ex() /// </summary> /// <param name="key"></param> /// <param name="digest"></param> public void Init(byte[] key, MessageDigest digest) { Native.HMAC_Init_ex(this.ptr, key, key.Length, digest.Handle, IntPtr.Zero); this.digest_size = digest.Size; this.initialized = true; }
public void VerifyHMAC(MessageDigest digest, string[] results) { byte[] hash = HMAC.Digest(digest, key, small_data); string str = BitConverter.ToString(hash); if (str != results[0]) { Console.WriteLine("{0} - Failed to calculate hash on {1}", digest.Name, small_data); Console.WriteLine("got {0} instead of {1}", str, results[0]); } else { Console.WriteLine("{0} - Test 1 passed.", digest.Name); } // Compute the large hash using (HMAC hmac = new HMAC()) { byte[] buf = Encoding.ASCII.GetBytes(new string('a', 1000)); hmac.Init(key, digest); for (int i = 0; i < 1000; i++) { hmac.Update(buf); } hash = hmac.DigestFinal(); // Check for error str = BitConverter.ToString(hash); if (str != results[1]) { Console.WriteLine("{0} - Failed to calculate hash on a*1000", digest.Name); Console.WriteLine("got {0} instead of {1}", str, results[1]); } else { Console.WriteLine("{0} - Test 2 passed.", digest.Name); } } }
/// <summary> /// Calls EVP_SignFinal() /// </summary> /// <param name="md"></param> /// <param name="bio"></param> /// <param name="pkey"></param> /// <returns></returns> public static byte[] Sign(MessageDigest md, BIO bio, CryptoKey pkey) { BIO bmd = BIO.MessageDigest(md); bmd.Push(bio); while (true) { ArraySegment<byte> bytes = bmd.ReadBytes(1024 * 4); if (bytes.Count == 0) break; } MessageDigestContext ctx = new MessageDigestContext(bmd); byte[] sig = new byte[pkey.Size]; uint len = (uint)sig.Length; Native.ExpectSuccess(Native.EVP_SignFinal(ctx.Handle, sig, ref len, pkey.Handle)); byte[] ret = new byte[len]; Buffer.BlockCopy(sig, 0, ret, 0, (int)len); return ret; }
/// <summary> /// Calls EVP_MD_CTX_create() then EVP_MD_CTX_init() /// </summary> /// <param name="md"></param> public MessageDigestContext(MessageDigest md) : base(Native.EVP_MD_CTX_create(), true) { Native.EVP_MD_CTX_init(this.ptr); this.md = md; }
/// <summary> /// Calls BIO_get_md_ctx() then BIO_get_md() /// </summary> /// <param name="bio"></param> public MessageDigestContext(BIO bio) : base(Native.ExpectNonNull(Native.BIO_get_md_ctx(bio.Handle)), false) { this.md = new MessageDigest(Native.ExpectNonNull(Native.BIO_get_md(bio.Handle)), false); }
/// <summary> /// Process and X509Request. This includes creating a new X509Certificate /// and signing this certificate with this CA's private key. /// </summary> /// <param name="request"></param> /// <param name="startTime"></param> /// <param name="endTime"></param> /// <param name="digest"></param> /// <returns></returns> public X509Certificate ProcessRequest(X509Request request, DateTime startTime, DateTime endTime, MessageDigest digest) { //using (CryptoKey pkey = request.PublicKey) //{ // if (!request.Verify(pkey)) // throw new Exception("Request signature validation failed"); //} X509Certificate cert = new X509Certificate( serial.Next(), request.Subject, this.caCert.Subject, request.PublicKey, startTime, endTime); if (this.cfg != null) this.cfg.ApplyExtensions("v3_ca", this.caCert, cert, request); cert.Sign(this.caKey, digest); return cert; }
/// <summary> /// Factory method that creates a X509CertificateAuthority instance with /// an internal self signed certificate. This method allows creation without /// the need for the Configuration file, X509V3Extensions may be added /// with the X509V3ExtensionList parameter /// </summary> /// <param name="seq"></param> /// <param name="key"></param> /// <param name="digest"></param> /// <param name="subject"></param> /// <param name="start"></param> /// <param name="validity"></param> /// <param name="extensions"></param> /// <returns></returns> public static X509CertificateAuthority SelfSigned( ISequenceNumber seq, CryptoKey key, MessageDigest digest, X509Name subject, DateTime start, TimeSpan validity, X509V3ExtensionList extensions) { X509Certificate cert = new X509Certificate( seq.Next(), subject, subject, key, start, start + validity); if (null != extensions) { foreach (X509V3ExtensionValue extValue in extensions) { X509Extension ext = new X509Extension(cert, cert, extValue.Name, extValue.IsCritical, extValue.Value); cert.AddExtension(ext); } } cert.Sign(key, digest); return new X509CertificateAuthority(cert, key, seq, null); }
/// <summary> /// Factory method that calls BIO_new() with BIO_f_md() /// </summary> /// <param name="md"></param> /// <returns></returns> public static BIO MessageDigest(MessageDigest md) { IntPtr ptr = Native.ExpectNonNull(Native.BIO_new(Native.BIO_f_md())); Native.BIO_set_md(ptr, md.Handle); return new BIO(ptr, true); }
/// <summary> /// Calls EVP_VerifyFinal() /// </summary> /// <param name="md"></param> /// <param name="bio"></param> /// <param name="sig"></param> /// <param name="pkey"></param> /// <returns></returns> public static bool Verify(MessageDigest md, BIO bio, byte[] sig, CryptoKey pkey) { BIO bmd = BIO.MessageDigest(md); bmd.Push(bio); while (true) { ArraySegment<byte> bytes = bmd.ReadBytes(1024 * 4); if (bytes.Count == 0) break; } MessageDigestContext ctx = new MessageDigestContext(bmd); int ret = Native.ExpectSuccess(Native.EVP_VerifyFinal(ctx.Handle, sig, (uint)sig.Length, pkey.Handle)); return ret == 1; }
/// <summary> /// Create a X509Request for this identity, using the specified name and digest. /// </summary> /// <param name="name"></param> /// <param name="digest"></param> /// <returns></returns> public X509Request CreateRequest(string name, MessageDigest digest) { var subject = new X509Name(name); var request = new X509Request(2, subject, key); request.Sign(key, digest); return request; }
/// <summary> /// Calls EVP_BytesToKey /// </summary> /// <param name="md"></param> /// <param name="salt"></param> /// <param name="data"></param> /// <param name="count"></param> /// <param name="iv"></param> /// <returns></returns> public byte[] BytesToKey(MessageDigest md, byte[] salt, byte[] data, int count, out byte[] iv) { int keylen = this.Cipher.KeyLength; if (keylen == 0) { keylen = 8; } byte[] key = new byte[keylen]; int ivlen = this.Cipher.IVLength; if (ivlen == 0) { ivlen = 8; } iv = new byte[ivlen]; Native.ExpectSuccess(Native.EVP_BytesToKey( this.cipher.Handle, md.Handle, salt, data, data.Length, count, key, iv)); return key; }
/// <summary> /// Sign this X509Request using the supplied key and digest. /// </summary> /// <param name="pkey"></param> /// <param name="digest"></param> public void Sign(CryptoKey pkey, MessageDigest digest) { if (Native.X509_REQ_sign(this.ptr, pkey.Handle, digest.Handle) == 0) throw new OpenSslException(); }