internal static bool CanProduceSha1Signature(AsymmetricAlgorithm algorithm) { #if NETFRAMEWORK algorithm.Dispose(); return(true); #else // We expect all non-Linux platforms to support SHA1 signatures, currently. if (!OperatingSystem.IsLinux()) { return(true); } switch (algorithm) { case ECDsa ecdsa: try { ecdsa.SignData(Array.Empty <byte>(), HashAlgorithmName.SHA1); return(true); } catch (CryptographicException) { return(false); } finally { algorithm.Dispose(); } case RSA rsa: try { rsa.SignData(Array.Empty <byte>(), HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1); return(true); } catch (CryptographicException) { return(false); } finally { algorithm.Dispose(); } default: throw new NotSupportedException($"Algorithm type {algorithm.GetType()} is not supported."); } #endif }
static Boolean deleteLegacyKey(AsymmetricAlgorithm privateKey) { if (privateKey == null) { return(false); } String keyContainer; String provName; UInt32 provType; switch (privateKey) { case RSACryptoServiceProvider rsaProv: keyContainer = rsaProv.CspKeyContainerInfo.KeyContainerName; provName = rsaProv.CspKeyContainerInfo.ProviderName; provType = (UInt32)rsaProv.CspKeyContainerInfo.ProviderType; break; case DSACryptoServiceProvider dsaProv: keyContainer = dsaProv.CspKeyContainerInfo.KeyContainerName; provName = dsaProv.CspKeyContainerInfo.ProviderName; provType = (UInt32)dsaProv.CspKeyContainerInfo.ProviderType; break; default: privateKey.Dispose(); return(false); } IntPtr phProv = IntPtr.Zero; Boolean status2 = false; Boolean status1 = AdvAPI.CryptAcquireContext( ref phProv, keyContainer, provName, provType, Wincrypt.CRYPT_DELETEKEYSET | nCrypt2.NCRYPT_MACHINE_KEY_FLAG); if (!status1) { status2 = AdvAPI.CryptAcquireContext( ref phProv, keyContainer, provName, provType, Wincrypt.CRYPT_DELETEKEYSET); } privateKey.Dispose(); return(status1 || status2); }
public void Dispose() { if (_disposeCryptoProvider && _signingKey != null) { _signingKey.Dispose(); } }
/// <summary> /// Create self signed cert /// </summary> /// <param name="signature"></param> /// <param name="subject"></param> /// <returns></returns> internal static AsymmetricAlgorithm CreateCsr(this SignatureType signature, string subject, out CertificateRequest csr) { AsymmetricAlgorithm alg = null; try { if (signature.IsRSA()) { var rsa = RSA.Create(); alg = rsa; csr = new CertificateRequest(X500DistinguishedNameEx.Create(subject), rsa, signature.ToHashAlgorithmName(), signature.ToRSASignaturePadding()); return(alg); } if (signature.IsECC()) { var ecdsa = ECDsa.Create(); alg = ecdsa; csr = new CertificateRequest(X500DistinguishedNameEx.Create(subject), ecdsa, signature.ToHashAlgorithmName()); return(alg); } throw new ArgumentException("Bad signature"); } catch { alg?.Dispose(); throw; } }
private void Dispose(bool Disposing) { if (!_disposed) { _asymAlgo.Dispose(); _disposed = true; } }
/// <summary> /// Performs the actual job of disposing the object. /// </summary> /// <param name="disposing"> /// Passes the information whether this method is called by <see cref="IDisposable.Dispose()"/> (explicitly or /// implicitly at the end of a <c>using</c> statement), or by the <see cref="M:~Signer()"/>. /// </param> /// <remarks> /// If the method is called with <paramref name="disposing"/><c>==true</c>, i.e. from <see cref="IDisposable.Dispose()"/>, it will try to release all managed resources /// (usually aggregated objects which implement <see cref="IDisposable"/> as well) and then it will release all unmanaged resources if any. /// If the parameter is <c>false</c> then the method will only try to release the unmanaged resources. /// </remarks> protected override void Dispose(bool disposing) { if (disposing) { _asymmetric.Dispose(); } base.Dispose(disposing); }
/// <summary> /// Performs the actual job of disposing the object. /// </summary> /// <param name="disposing"> /// Passes the information whether this method is called by <see cref="Dispose()"/> (explicitly or /// implicitly at the end of a <c>using</c> statement), or by the <see cref="M:~RsaXmlSigner"/>. /// </param> /// <remarks> /// If the method is called with <paramref name="disposing"/><c>==true</c>, i.e. from <see cref="Dispose()"/>, /// it will try to release all managed resources (usually aggregated objects which implement <see cref="IDisposable"/> as well) /// and then it will release all unmanaged resources if any. If the parameter is <c>false</c> then /// the method will only try to release the unmanaged resources. /// </remarks> protected virtual void Dispose(bool disposing) { // if it is disposed or in a process of disposing - return. if (Interlocked.Exchange(ref _disposed, 1) != 0) { return; } if (disposing) { _asymmetric.Dispose(); } }
/// <summary> /// Create a certificate using the established subject, key, and optional extensions using /// the provided certificate as the issuer. /// </summary> /// <param name="issuerCertificate"> /// An X509Certificate2 instance representing the issuing Certificate Authority (CA). /// </param> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <param name="serialNumber"> /// The serial number to use for the new certificate. This value should be unique per issuer. /// The value is interpreted as an unsigned (big) integer in big endian byte ordering. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// not assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="issuerCertificate"/> is null.</exception> /// <exception cref="ArgumentException"> /// The <see cref="X509Certificate2.HasPrivateKey"/> value for <paramref name="issuerCertificate"/> is false. /// </exception> /// <exception cref="ArgumentException"> /// The type of signing key represented by <paramref name="issuerCertificate"/> could not be determined. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notBefore"/>. /// </exception> /// <exception cref="ArgumentException"><paramref name="serialNumber"/> is null or has length 0.</exception> public X509Certificate2 Create( X509Certificate2 issuerCertificate, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber) { if (issuerCertificate == null) { throw new ArgumentNullException(nameof(issuerCertificate)); } if (!issuerCertificate.HasPrivateKey) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerRequiresPrivateKey, nameof(issuerCertificate)); } AsymmetricAlgorithm key = null; string keyAlgorithm = issuerCertificate.GetKeyAlgorithm(); X509SignatureGenerator generator; try { switch (keyAlgorithm) { case Oids.RsaRsa: RSA rsa = issuerCertificate.GetRSAPrivateKey(); key = rsa; generator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); break; case Oids.Ecc: ECDsa ecdsa = issuerCertificate.GetECDsaPrivateKey(); key = ecdsa; generator = X509SignatureGenerator.CreateForECDsa(ecdsa); break; default: throw new ArgumentException( SR.Format(SR.Cryptography_UnknownKeyAlgorithm, keyAlgorithm), nameof(issuerCertificate)); } return(Create(issuerCertificate.SubjectName, generator, notBefore, notAfter, serialNumber)); } finally { key?.Dispose(); } }
private void Dispose(bool disposing) { if (_disposed) { return; } if (disposing) { if (_asymAlgo != null) { _asymAlgo.Dispose(); } } _disposed = true; }
void releaseUnmanagedResources() { // dispose public key handle phPubKey.Dispose(); if (isCng) { // dispose CNG private key handle phPrivKey.Dispose(); } else { // dispose legacy private CSP key legacyKey?.Dispose(); legacyKey = null; } //TODO: Crypt32.CertFreeCertificateContext(SignerCertificate.Handle); SignerCertificate = null; disposed = true; }
public void TearDown() { try { _publicKey.Dispose(); } finally { _publicKey = null; } try { _privateKey.Dispose(); } finally { _privateKey = null; } }
protected bool VerifyWithClientCertificate(byte[] data, byte[] signature, SignatureAlgorithm signatureAlgorithm) { AsymmetricAlgorithm asymmetric = null; var cert = _clientCertificates.First(); if (cert.PublicKey.Oid.FriendlyName == "RSA") { asymmetric = cert.GetRSAPublicKey(); } else if (cert.PublicKey.Oid.FriendlyName == "ECC") { asymmetric = cert.GetECDsaPublicKey(); } else { throw new NotSupportedException($"Client Certificate Type {cert.PublicKey.Oid.FriendlyName} NotSupported"); } var verified = _params.Cipher.SignatureVerify(data, signature, signatureAlgorithm, asymmetric); asymmetric.Dispose(); return(verified); }
protected byte[] MakeSignatureWithCertificate(byte[] signdata) { AsymmetricAlgorithm asymmetric = null; using (var cert = new X509Certificate2(_prvkeyfile)) { if (cert.PublicKey.Oid.FriendlyName == "RSA") { asymmetric = cert.GetRSAPrivateKey(); } else if (cert.PublicKey.Oid.FriendlyName == "ECC") { asymmetric = cert.GetECDsaPrivateKey(); } else { throw new NotSupportedException($"Server Certificate Type {cert.PublicKey.Oid.FriendlyName} NotSupported"); } } var signature = _params.Cipher.Signature(signdata, _params.SignatureAlgorithm, asymmetric); asymmetric.Dispose(); return(signature); }
/// <summary> /// Create a certificate using the established subject, key, and optional extensions using /// the provided certificate as the issuer. /// </summary> /// <param name="issuerCertificate"> /// An X509Certificate2 instance representing the issuing Certificate Authority (CA). /// </param> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <param name="serialNumber"> /// The serial number to use for the new certificate. This value should be unique per issuer. /// The value is interpreted as an unsigned (big) integer in big endian byte ordering. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// not assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="issuerCertificate"/> is null.</exception> /// <exception cref="ArgumentException"> /// The <see cref="X509Certificate2.HasPrivateKey"/> value for <paramref name="issuerCertificate"/> is false. /// </exception> /// <exception cref="ArgumentException"> /// The type of signing key represented by <paramref name="issuerCertificate"/> could not be determined. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notBefore"/>. /// </exception> /// <exception cref="ArgumentException"><paramref name="serialNumber"/> has length 0.</exception> /// <exception cref="ArgumentException"> /// <paramref name="issuerCertificate"/> has a different key algorithm than the requested certificate. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="issuerCertificate"/> is an RSA certificate and this object was created via a constructor /// which does not accept a <see cref="RSASignaturePadding"/> value. /// </exception> public X509Certificate2 Create( X509Certificate2 issuerCertificate, DateTimeOffset notBefore, DateTimeOffset notAfter, ReadOnlySpan <byte> serialNumber) { if (issuerCertificate == null) { throw new ArgumentNullException(nameof(issuerCertificate)); } if (!issuerCertificate.HasPrivateKey) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerRequiresPrivateKey, nameof(issuerCertificate)); } if (notAfter < notBefore) { throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed); } if (serialNumber.IsEmpty) { throw new ArgumentException(SR.Arg_EmptyOrNullArray, nameof(serialNumber)); } if (issuerCertificate.PublicKey.Oid.Value != PublicKey.Oid.Value) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_AlgorithmMustMatch, issuerCertificate.PublicKey.Oid.Value, PublicKey.Oid.Value), nameof(issuerCertificate)); } DateTime notBeforeLocal = notBefore.LocalDateTime; if (notBeforeLocal < issuerCertificate.NotBefore) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotBeforeNotNested, notBeforeLocal, issuerCertificate.NotBefore), nameof(notBefore)); } DateTime notAfterLocal = notAfter.LocalDateTime; // Round down to the second, since that's the cert accuracy. // This makes one method which uses the same DateTimeOffset for chained notAfters // not need to do the rounding locally. long notAfterLocalTicks = notAfterLocal.Ticks; long fractionalSeconds = notAfterLocalTicks % TimeSpan.TicksPerSecond; notAfterLocalTicks -= fractionalSeconds; notAfterLocal = new DateTime(notAfterLocalTicks, notAfterLocal.Kind); if (notAfterLocal > issuerCertificate.NotAfter) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotAfterNotNested, notAfterLocal, issuerCertificate.NotAfter), nameof(notAfter)); } // Check the Basic Constraints and Key Usage extensions to help identify inappropriate certificates. // Note that this is not a security check. The system library backing X509Chain will use these same criteria // to determine if a chain is valid; and a user can easily call the X509SignatureGenerator overload to // bypass this validation. We're simply helping them at signing time understand that they've // chosen the wrong cert. var basicConstraints = (X509BasicConstraintsExtension?)issuerCertificate.Extensions[Oids.BasicConstraints2]; var keyUsage = (X509KeyUsageExtension?)issuerCertificate.Extensions[Oids.KeyUsage]; if (basicConstraints == null) { throw new ArgumentException(SR.Cryptography_CertReq_BasicConstraintsRequired, nameof(issuerCertificate)); } if (!basicConstraints.CertificateAuthority) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerBasicConstraintsInvalid, nameof(issuerCertificate)); } if (keyUsage != null && (keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == 0) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerKeyUsageInvalid, nameof(issuerCertificate)); } AsymmetricAlgorithm?key = null; string keyAlgorithm = issuerCertificate.GetKeyAlgorithm(); X509SignatureGenerator generator; try { switch (keyAlgorithm) { case Oids.Rsa: if (_rsaPadding == null) { throw new InvalidOperationException(SR.Cryptography_CertReq_RSAPaddingRequired); } RSA?rsa = issuerCertificate.GetRSAPrivateKey(); key = rsa; generator = X509SignatureGenerator.CreateForRSA(rsa !, _rsaPadding); break; case Oids.EcPublicKey: ECDsa?ecdsa = issuerCertificate.GetECDsaPrivateKey(); key = ecdsa; generator = X509SignatureGenerator.CreateForECDsa(ecdsa !); break; default: throw new ArgumentException( SR.Format(SR.Cryptography_UnknownKeyAlgorithm, keyAlgorithm), nameof(issuerCertificate)); } return(Create(issuerCertificate.SubjectName, generator, notBefore, notAfter, serialNumber)); } finally { key?.Dispose(); } }
private byte[] Build( X509Certificate2 issuerCertificate, BigInteger crlNumber, DateTimeOffset nextUpdate, DateTimeOffset thisUpdate, HashAlgorithmName hashAlgorithm, RSASignaturePadding?rsaSignaturePadding) { ArgumentNullException.ThrowIfNull(issuerCertificate); if (!issuerCertificate.HasPrivateKey) { throw new ArgumentException( SR.Cryptography_CertReq_IssuerRequiresPrivateKey, nameof(issuerCertificate)); } if (crlNumber < 0) { throw new ArgumentOutOfRangeException(nameof(crlNumber), SR.ArgumentOutOfRange_NeedNonNegNum); } if (nextUpdate <= thisUpdate) { throw new ArgumentException(SR.Cryptography_CRLBuilder_DatesReversed); } ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); // Check the Basic Constraints and Key Usage extensions to help identify inappropriate certificates. // Note that this is not a security check. The system library backing X509Chain will use these same criteria // to determine if the CRL is valid; and a user can easily call the X509SignatureGenerator overload to // bypass this validation. We're simply helping them at signing time understand that they've // chosen the wrong cert. var basicConstraints = (X509BasicConstraintsExtension?)issuerCertificate.Extensions[Oids.BasicConstraints2]; var keyUsage = (X509KeyUsageExtension?)issuerCertificate.Extensions[Oids.KeyUsage]; var subjectKeyIdentifier = (X509SubjectKeyIdentifierExtension?)issuerCertificate.Extensions[Oids.SubjectKeyIdentifier]; if (basicConstraints == null) { throw new ArgumentException( SR.Cryptography_CertReq_BasicConstraintsRequired, nameof(issuerCertificate)); } if (!basicConstraints.CertificateAuthority) { throw new ArgumentException( SR.Cryptography_CertReq_IssuerBasicConstraintsInvalid, nameof(issuerCertificate)); } if (keyUsage != null && (keyUsage.KeyUsages & X509KeyUsageFlags.CrlSign) == 0) { throw new ArgumentException( SR.Cryptography_CRLBuilder_IssuerKeyUsageInvalid, nameof(issuerCertificate)); } AsymmetricAlgorithm?key = null; string keyAlgorithm = issuerCertificate.GetKeyAlgorithm(); X509SignatureGenerator generator; try { switch (keyAlgorithm) { case Oids.Rsa: if (rsaSignaturePadding is null) { throw new ArgumentException(SR.Cryptography_CertReq_RSAPaddingRequired); } RSA?rsa = issuerCertificate.GetRSAPrivateKey(); key = rsa; generator = X509SignatureGenerator.CreateForRSA(rsa !, rsaSignaturePadding); break; case Oids.EcPublicKey: ECDsa?ecdsa = issuerCertificate.GetECDsaPrivateKey(); key = ecdsa; generator = X509SignatureGenerator.CreateForECDsa(ecdsa !); break; default: throw new ArgumentException( SR.Format(SR.Cryptography_UnknownKeyAlgorithm, keyAlgorithm), nameof(issuerCertificate)); } X509AuthorityKeyIdentifierExtension akid; if (subjectKeyIdentifier is not null) { akid = X509AuthorityKeyIdentifierExtension.CreateFromSubjectKeyIdentifier(subjectKeyIdentifier); } else { akid = X509AuthorityKeyIdentifierExtension.CreateFromIssuerNameAndSerialNumber( issuerCertificate.IssuerName, issuerCertificate.SerialNumberBytes.Span); } return(Build( issuerCertificate.SubjectName, generator, crlNumber, nextUpdate, thisUpdate, hashAlgorithm, akid)); } finally { key?.Dispose(); } }