public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.Ecc) { return DecodeECDsaPublicKey((CertificatePal)certificatePal); } int algId = OidInfo.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId; switch (algId) { case AlgId.CALG_RSA_KEYX: case AlgId.CALG_RSA_SIGN: { byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue); CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob); return new RSACng(cngKey); } #if !NETNATIVE case AlgId.CALG_DSS_SIGN: { byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters); DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(keyBlob); return dsa; } #endif default: throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); } }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } TimeSpan remainingDownloadTime = timeout; var leaf = new X509Certificate2(cert.Handle); var downloaded = new HashSet<X509Certificate2>(); var systemTrusted = new HashSet<X509Certificate2>(); HashSet<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, systemTrusted, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, systemTrusted, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, ref remainingDownloadTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
/// <summary> /// Does not throw on error. Returns null ChainPal instead. /// </summary> public static ChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CertificatePal certificatePal = (CertificatePal)cert; unsafe { using (SafeCertStoreHandle extraStoreHandle = ConvertExtraStoreToSafeHandle(extraStore)) { CERT_CHAIN_PARA chainPara = new CERT_CHAIN_PARA(); chainPara.cbSize = Marshal.SizeOf<CERT_CHAIN_PARA>(); int applicationPolicyCount; using (SafeHandle applicationPolicyOids = applicationPolicy.ToLpstrArray(out applicationPolicyCount)) { if (!applicationPolicyOids.IsInvalid) { chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedUsage.Usage.cUsageIdentifier = applicationPolicyCount; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle(); } int certificatePolicyCount; using (SafeHandle certificatePolicyOids = certificatePolicy.ToLpstrArray(out certificatePolicyCount)) { if (!certificatePolicyOids.IsInvalid) { chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount; chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle(); } chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds); FILETIME ft = FILETIME.FromDateTime(verificationTime); CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag); ChainEngine chainEngine = useMachineContext ? ChainEngine.HCCE_LOCAL_MACHINE : ChainEngine.HCCE_CURRENT_USER; SafeX509ChainHandle chain; if (!Interop.crypt32.CertGetCertificateChain(chainEngine, certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) return null; return new ChainPal(chain); } } } } }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { switch (oid.Value) { case Oids.RsaRsa: return BuildRsaPublicKey(encodedKeyValue); } // NotSupportedException is what desktop and CoreFx-Windows throw in this situation. throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { return new OpenSslX509ChainProcessor(); }
internal static bool TryReadX509Der(byte[] rawData, out ICertificatePal certPal) { SafeX509Handle certHandle = Interop.Crypto.DecodeX509(rawData, rawData.Length); if (certHandle.IsInvalid) { certHandle.Dispose(); certPal = null; return false; } certPal = new OpenSslX509CertificateReader(certHandle); return true; }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.Ecc && certificatePal != null) { return ((OpenSslX509CertificateReader)certificatePal).GetECDsaPublicKey(); } switch (oid.Value) { case Oids.RsaRsa: return BuildRsaPublicKey(encodedKeyValue); } // NotSupportedException is what desktop and CoreFx-Windows throw in this situation. throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); }
public static IExportPal FromCertificate(ICertificatePal cert) { CertificatePal certificatePal = (CertificatePal)cert; SafeCertStoreHandle certStore = Interop.crypt32.CertOpenStore( CertStoreProvider.CERT_STORE_PROV_MEMORY, CertEncodingType.All, IntPtr.Zero, CertStoreFlags.CERT_STORE_ENUM_ARCHIVED_FLAG | CertStoreFlags.CERT_STORE_CREATE_NEW_FLAG | CertStoreFlags.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, null); if (certStore.IsInvalid) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; if (!Interop.crypt32.CertAddCertificateLinkToStore(certStore, certificatePal.CertContext, CertStoreAddDisposition.CERT_STORE_ADD_ALWAYS, IntPtr.Zero)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException();; return new StorePal(certStore); }
public void Remove(ICertificatePal certificate) { unsafe { SafeCertContextHandle existingCertContext = ((CertificatePal)certificate).CertContext; SafeCertContextHandle enumCertContext = null; CERT_CONTEXT* pCertContext = existingCertContext.CertContext; if (!Interop.crypt32.CertFindCertificateInStore(_certStore, CertFindType.CERT_FIND_EXISTING, pCertContext, ref enumCertContext)) return; // The certificate is not present in the store, simply return. CERT_CONTEXT* pCertContextToDelete = enumCertContext.Disconnect(); // CertDeleteCertificateFromContext always frees the context (even on error) if (!Interop.crypt32.CertDeleteCertificateFromStore(pCertContextToDelete)) throw Marshal.GetLastWin32Error().ToCryptographicException(); GC.KeepAlive(existingCertContext); } }
private static bool TryReadPkcs7Der( byte[] rawData, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { using (SafePkcs7Handle pkcs7 = Interop.Crypto.DecodePkcs7(rawData, rawData.Length)) { if (pkcs7.IsInvalid) { certPal = null; certPals = null; return false; } return TryReadPkcs7(pkcs7, single, out certPal, out certPals); } }
private static bool TryReadPkcs7Der( SafeBioHandle bio, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { using (SafePkcs7Handle pkcs7 = Interop.Crypto.D2IPkcs7Bio(bio)) { if (pkcs7.IsInvalid) { certPal = null; certPals = null; return false; } return TryReadPkcs7(pkcs7, single, out certPal, out certPals); } }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { CheckRevocationMode(revocationMode); // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } TimeSpan remainingDownloadTime = timeout; X509Certificate2 leaf = new X509Certificate2(cert.Handle); List<X509Certificate2> downloaded = new List<X509Certificate2>(); List<X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, downloaded, applicationPolicy, certificatePolicy, verificationTime); if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } return chain; }
private static bool TryReadPkcs7Der( SafeBioHandle bio, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { SafePkcs7Handle pkcs7 = Interop.libcrypto.d2i_PKCS7_bio(bio, IntPtr.Zero); if (pkcs7.IsInvalid) { certPal = null; certPals = null; return false; } using (pkcs7) { return TryReadPkcs7(pkcs7, single, out certPal, out certPals); } }
private static unsafe bool TryReadPkcs7Der( byte[] rawData, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { SafePkcs7Handle pkcs7 = Interop.libcrypto.OpenSslD2I( (ptr, b, i) => Interop.libcrypto.d2i_PKCS7(ptr, b, i), rawData, checkHandle: false); if (pkcs7.IsInvalid) { certPal = null; certPals = null; return false; } using (pkcs7) { return TryReadPkcs7(pkcs7, single, out certPal, out certPals); } }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { switch (oid.Value) { case Oids.RsaRsa: return(BuildRsaPublicKey(encodedKeyValue)); case Oids.Ecc: return(((OpenSslX509CertificateReader)certificatePal).GetECDsaPublicKey()); } // NotSupportedException is what desktop and CoreFx-Windows throw in this situation. throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); }
private static IStorePal SingleCertToStorePal(ICertificatePal singleCert) { return new CollectionBackedStoreProvider(new X509Certificate2(singleCert)); }
internal static bool TryReadPkcs7Pem(SafeBioHandle bio, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs7Pem(bio, true, out certPal, out ignored); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, X509Certificate2Collection customTrustStore, X509ChainTrustMode trustMode, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } // Until we support the Disallowed store, ensure it's empty (which is done by the ctor) using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly)) { } TimeSpan remainingDownloadTime = timeout; OpenSslX509ChainProcessor chainPal = OpenSslX509ChainProcessor.InitiateChain( ((OpenSslX509CertificateReader)cert).SafeHandle, customTrustStore, trustMode, verificationTime, remainingDownloadTime); Interop.Crypto.X509VerifyStatusCode status = chainPal.FindFirstChain(extraStore); if (!OpenSslX509ChainProcessor.IsCompleteChain(status)) { List <X509Certificate2> tmp = null; status = chainPal.FindChainViaAia(ref tmp); if (tmp != null) { if (status == Interop.Crypto.X509VerifyStatusCode.X509_V_OK) { SaveIntermediateCertificates(tmp); } foreach (X509Certificate2 downloaded in tmp) { downloaded.Dispose(); } } } // In NoCheck+OK then we don't need to build the chain any more, we already // know it's error-free. So skip straight to finish. if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_OK || revocationMode != X509RevocationMode.NoCheck) { if (OpenSslX509ChainProcessor.IsCompleteChain(status)) { chainPal.CommitToChain(); chainPal.ProcessRevocation(revocationMode, revocationFlag); } } chainPal.Finish(applicationPolicy, certificatePolicy); #if DEBUG if (chainPal.ChainElements.Length > 0) { X509Certificate2 reportedLeaf = chainPal.ChainElements[0].Certificate; Debug.Assert(reportedLeaf != null, "reportedLeaf != null"); Debug.Assert(!ReferenceEquals(cert, reportedLeaf.Pal), "!ReferenceEquals(cert, reportedLeaf.Pal)"); } #endif return(chainPal); }
private static bool TryReadPkcs12( OpenSslPkcs12Reader pfx, string password, bool single, out ICertificatePal readPal, out List<ICertificatePal> readCerts) { pfx.Decrypt(password); ICertificatePal first = null; List<ICertificatePal> certs = null; if (!single) { certs = new List<ICertificatePal>(); } foreach (OpenSslX509CertificateReader certPal in pfx.ReadCertificates()) { if (single) { // When requesting an X509Certificate2 from a PFX only the first entry is // returned. Other entries should be disposed. if (first == null) { first = certPal; } else if (certPal.HasPrivateKey && !first.HasPrivateKey) { first.Dispose(); first = certPal; } else { certPal.Dispose(); } } else { certs.Add(certPal); } } readPal = first; readCerts = certs; return true; }
internal static bool TryReadPkcs12(SafeBioHandle bio, string password, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs12(bio, password, true, out certPal, out ignored); }
private static bool TryReadPkcs7( SafePkcs7Handle pkcs7, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { List<ICertificatePal> readPals = single ? null : new List<ICertificatePal>(); using (SafeSharedX509StackHandle certs = Interop.Crypto.GetPkcs7Certificates(pkcs7)) { int count = Interop.Crypto.GetX509StackFieldCount(certs); if (single) { // In single mode for a PKCS#7 signed or signed-and-enveloped file we're supposed to return // the certificate which signed the PKCS#7 file. // // X509Certificate2Collection::Export(X509ContentType.Pkcs7) claims to be a signed PKCS#7, // but doesn't emit a signature block. So this is hard to test. // // TODO(2910): Figure out how to extract the signing certificate, when it's present. throw new CryptographicException(SR.Cryptography_X509_PKCS7_NoSigner); } for (int i = 0; i < count; i++) { // Use FromHandle to duplicate the handle since it would otherwise be freed when the PKCS7 // is Disposed. IntPtr certHandle = Interop.Crypto.GetX509StackField(certs, i); ICertificatePal pal = CertificatePal.FromHandle(certHandle); readPals.Add(pal); } } certPal = null; certPals = readPals; return true; }
public static IExportPal FromCertificate(ICertificatePal cert) { return(new ExportProvider(cert)); }
private static ILoaderPal SingleCertToLoaderPal(ICertificatePal singleCert) { return(new SingleCertLoader(singleCert)); }
public static IExportPal FromCertificate(ICertificatePal cert) { return(new AppleCertificateExporter(cert)); }
public static IStorePal FromCertificate(ICertificatePal cert) { throw new NotImplementedException(); }
internal X509Certificate2(ICertificatePal pal) : base(pal) { }
public void Remove(ICertificatePal certPal) { OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { bool hadCandidates; string currentFilename = FindExistingFilename(copy, _storePath, out hadCandidates); if (currentFilename != null) { if (_readOnly) { // Windows compatibility, the readonly check isn't done until after a match is found. throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly); } File.Delete(currentFilename); } } }
private static IStorePal SingleCertToStorePal(ICertificatePal singleCert) { return(new CollectionBackedStoreProvider(new X509Certificate2(singleCert))); }
private static bool TryReadPkcs7Pem( byte[] rawData, bool single, out ICertificatePal certPal, out List<ICertificatePal> certPals) { using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio()) { Interop.Crypto.CheckValidOpenSslHandle(bio); Interop.Crypto.BioWrite(bio, rawData, rawData.Length); return TryReadPkcs7Pem(bio, single, out certPal, out certPals); } }
internal static bool TryReadX509Der(SafeBioHandle bio, out ICertificatePal fromBio) { SafeX509Handle cert = Interop.Crypto.ReadX509AsDerFromBio(bio); if (cert.IsInvalid) { cert.Dispose(); fromBio = null; return false; } fromBio = new OpenSslX509CertificateReader(cert); return true; }
internal static bool TryReadPkcs12(byte[] rawData, string password, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs12(rawData, password, true, out certPal, out ignored); }
public void Add(ICertificatePal certPal) { if (_readOnly) { // Windows compatibility: Remove only throws when it needs to do work, add throws always. throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly); } // This may well be the first time that we've added something to this store. Directory.CreateDirectory(_storePath); uint userId = Interop.Sys.GetEUid(); EnsureDirectoryPermissions(_storePath, userId); OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string thumbprint = copy.Thumbprint; bool findOpenSlot; // The odds are low that we'd have a thumbprint collision, but check anyways. string existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot); if (existingFilename != null) { if (!copy.HasPrivateKey) { return; } try { using (X509Certificate2 fromFile = new X509Certificate2(existingFilename)) { if (fromFile.HasPrivateKey) { // We have a private key, the file has a private key, we're done here. return; } } } catch (CryptographicException) { // We can't read this file anymore, but a moment ago it was this certificate, // so go ahead and overwrite it. } } string destinationFilename; FileMode mode = FileMode.CreateNew; if (existingFilename != null) { destinationFilename = existingFilename; mode = FileMode.Create; } else if (findOpenSlot) { destinationFilename = FindOpenSlot(thumbprint); } else { destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension); } using (FileStream stream = new FileStream(destinationFilename, mode)) { EnsureFilePermissions(stream, userId); byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12); stream.Write(pkcs12, 0, pkcs12.Length); } } }
private static bool TryReadPkcs12( SafeBioHandle bio, string password, bool single, out ICertificatePal readPal, out List<ICertificatePal> readCerts) { // DER-PKCS12 OpenSslPkcs12Reader pfx; if (!OpenSslPkcs12Reader.TryRead(bio, out pfx)) { readPal = null; readCerts = null; return false; } using (pfx) { return TryReadPkcs12(pfx, password, single, out readPal, out readCerts); } }
internal static bool TryReadX509Pem(SafeBioHandle bio, out ICertificatePal certPal) { SafeX509Handle cert = Interop.Crypto.PemReadX509FromBio(bio); if (cert.IsInvalid) { cert.Dispose(); certPal = null; return false; } certPal = new OpenSslX509CertificateReader(cert); return true; }
internal void OpenTrustHandle( ICertificatePal leafCert, X509Certificate2Collection?extraStore, X509RevocationMode revocationMode, X509Certificate2Collection customTrustStore, X509ChainTrustMode trustMode) { _revocationMode = revocationMode; SafeCreateHandle policiesArray = PreparePoliciesArray(revocationMode != X509RevocationMode.NoCheck); SafeCreateHandle certsArray = PrepareCertsArray(leafCert, extraStore, customTrustStore, trustMode); int osStatus; SafeX509ChainHandle chain; int ret = Interop.AppleCrypto.AppleCryptoNative_X509ChainCreate( certsArray, policiesArray, out chain, out osStatus); if (ret == 1) { if (trustMode == X509ChainTrustMode.CustomRootTrust) { SafeCreateHandle customCertsArray = s_emptyArray; if (customTrustStore != null && customTrustStore.Count > 0) { customCertsArray = PrepareCustomCertsArray(customTrustStore); } try { int error = Interop.AppleCrypto.X509ChainSetTrustAnchorCertificates(chain, customCertsArray); if (error != 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(error); } } finally { if (customCertsArray != s_emptyArray) { customCertsArray.Dispose(); } } } _chainHandle = chain; return; } chain.Dispose(); if (ret == 0) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus); } Debug.Fail($"AppleCryptoNative_X509ChainCreate returned unexpected return value {ret}"); throw new CryptographicException(); }
private static string GetCertificateHashString(ICertificatePal certPal) { return(X509Certificate.GetCertHashString(HashAlgorithmName.SHA256, certPal)); }
internal static bool TryReadPkcs7Pem(byte[] rawData, out ICertificatePal certPal) { List<ICertificatePal> ignored; return TryReadPkcs7Pem(rawData, true, out certPal, out ignored); }
internal X509Certificate(ICertificatePal pal) { Debug.Assert(pal != null); Pal = pal; }
public static IStorePal FromCertificate(ICertificatePal cert) { ICertificatePal duplicatedHandles = ((OpenSslX509CertificateReader)cert).DuplicateHandles(); return new CollectionBackedStoreProvider(new X509Certificate2(duplicatedHandles)); }
public void Add(ICertificatePal certPal) { if (_readOnly) { // Windows compatibility: Remove only throws when it needs to do work, add throws always. throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly); } // This may well be the first time that we've added something to this store. Directory.CreateDirectory(_storePath); uint userId = Interop.Sys.GetEUid(); EnsureDirectoryPermissions(_storePath, userId); OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string thumbprint = copy.Thumbprint; bool findOpenSlot; // The odds are low that we'd have a thumbprint collision, but check anyways. string existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot); if (existingFilename != null) { if (!copy.HasPrivateKey) { return; } try { using (X509Certificate2 fromFile = new X509Certificate2(existingFilename)) { if (fromFile.HasPrivateKey) { // We have a private key, the file has a private key, we're done here. return; } } } catch (CryptographicException) { // We can't read this file anymore, but a moment ago it was this certificate, // so go ahead and overwrite it. } } string destinationFilename; FileMode mode = FileMode.CreateNew; if (existingFilename != null) { destinationFilename = existingFilename; mode = FileMode.Create; } else if (findOpenSlot) { destinationFilename = FindOpenSlot(thumbprint); } else { destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension); } using (FileStream stream = new FileStream(destinationFilename, mode)) { EnsureFilePermissions(stream, userId); byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12); stream.Write(pkcs12, 0, pkcs12.Length); } } }
public static IStorePal FromCertificate(ICertificatePal cert) { ICertificatePal duplicatedHandles = ((OpenSslX509CertificateReader)cert).DuplicateHandles(); return(new CollectionBackedStoreProvider(new X509Certificate2(duplicatedHandles))); }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { const int errSecInvalidKeyRef = -67712; const int errSecUnsupportedKeySize = -67735; AppleCertificatePal applePal = certificatePal as AppleCertificatePal; if (applePal != null) { SafeSecKeyRefHandle key = Interop.AppleCrypto.X509GetPublicKey(applePal.CertificateHandle); switch (oid.Value) { case Oids.RsaRsa: Debug.Assert(!key.IsInvalid); return(new RSAImplementation.RSASecurityTransforms(key)); case Oids.DsaDsa: if (key.IsInvalid) { // SecCertificateCopyKey returns null for DSA, so fall back to manually building it. return(DecodeDsaPublicKey(encodedKeyValue, encodedParameters)); } return(new DSAImplementation.DSASecurityTransforms(key)); case Oids.Ecc: // If X509GetPublicKey uses the new SecCertificateCopyKey API it can return an invalid // key reference for unsupported algorithms. This currently happens for the BrainpoolP160r1 // algorithm in the test suite (as of macOS Mojave Developer Preview 4). if (key.IsInvalid) { throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecInvalidKeyRef); } // EccGetKeySizeInBits can fail for two reasons. First, the Apple implementation has changed // and we receive values from API that were not previously handled. In that case the CoreFX // implementation will need to be adjusted to handle these values. Second, we deliberately // return 0 from the native code to prevent hitting buggy API implementations in Apple code // later. if (Interop.AppleCrypto.EccGetKeySizeInBits(key) == 0) { key.Dispose(); throw Interop.AppleCrypto.CreateExceptionForOSStatus(errSecUnsupportedKeySize); } return(new ECDsaImplementation.ECDsaSecurityTransforms(key)); } key.Dispose(); } else { switch (oid.Value) { case Oids.RsaRsa: return(DecodeRsaPublicKey(encodedKeyValue)); case Oids.DsaDsa: return(DecodeDsaPublicKey(encodedKeyValue, encodedParameters)); } } throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); }
internal static bool TryReadX509Pem(byte[] rawData, out ICertificatePal certPal) { using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio()) { Interop.Crypto.CheckValidOpenSslHandle(bio); Interop.Crypto.BioWrite(bio, rawData, rawData.Length); return TryReadX509Pem(bio, out certPal); } }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.Ecc && certificatePal != null) { return(DecodeECDsaPublicKey((CertificatePal)certificatePal)); } int algId = Interop.Crypt32.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId; switch (algId) { case AlgId.CALG_RSA_KEYX: case AlgId.CALG_RSA_SIGN: { byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue); CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob); return(new RSACng(cngKey)); } #if !NETNATIVE case AlgId.CALG_DSS_SIGN: { byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters); DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(keyBlob); return(dsa); } #endif default: throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); } }
public void Remove(ICertificatePal cert) { throw new InvalidOperationException(); }
public static IChainPal BuildChain( bool useMachineContext, ICertificatePal cert, X509Certificate2Collection extraStore, OidCollection applicationPolicy, OidCollection certificatePolicy, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, DateTime verificationTime, TimeSpan timeout) { // An input value of 0 on the timeout is "take all the time you need". if (timeout == TimeSpan.Zero) { timeout = TimeSpan.MaxValue; } // Let Unspecified mean Local, so only convert if the source was UTC. // // Converge on Local instead of UTC because OpenSSL is going to assume we gave it // local time. if (verificationTime.Kind == DateTimeKind.Utc) { verificationTime = verificationTime.ToLocalTime(); } // Until we support the Disallowed store, ensure it's empty (which is done by the ctor) using (new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser, OpenFlags.ReadOnly)) { } TimeSpan remainingDownloadTime = timeout; using (var leaf = new X509Certificate2(cert.Handle)) { GC.KeepAlive(cert); // ensure cert's safe handle isn't finalized while raw handle is in use var downloaded = new HashSet <X509Certificate2>(); var systemTrusted = new HashSet <X509Certificate2>(); HashSet <X509Certificate2> candidates = OpenSslX509ChainProcessor.FindCandidates( leaf, extraStore, downloaded, systemTrusted, ref remainingDownloadTime); IChainPal chain = OpenSslX509ChainProcessor.BuildChain( leaf, candidates, systemTrusted, applicationPolicy, certificatePolicy, revocationMode, revocationFlag, verificationTime, ref remainingDownloadTime); #if DEBUG if (chain.ChainElements.Length > 0) { X509Certificate2 reportedLeaf = chain.ChainElements[0].Certificate; Debug.Assert(reportedLeaf != null, "reportedLeaf != null"); Debug.Assert(reportedLeaf.Equals(leaf), "reportedLeaf.Equals(leaf)"); Debug.Assert(!ReferenceEquals(reportedLeaf, leaf), "!ReferenceEquals(reportedLeaf, leaf)"); } #endif if (chain.ChainStatus.Length == 0 && downloaded.Count > 0) { SaveIntermediateCertificates(chain.ChainElements, downloaded); } // Everything we put into the chain has been cloned, dispose all the originals. systemTrusted.DisposeAll(); downloaded.DisposeAll(); // Candidate certs which came from extraStore should NOT be disposed, since they came // from outside. var extraStoreByReference = new HashSet <X509Certificate2>( ReferenceEqualityComparer <X509Certificate2> .Instance); foreach (X509Certificate2 extraCert in extraStore) { extraStoreByReference.Add(extraCert); } foreach (X509Certificate2 candidate in candidates) { if (!extraStoreByReference.Contains(candidate)) { candidate.Dispose(); } } return(chain); } }