public static void DisplayX509Certificate2 (NSObject sender, X509Certificate2 cert) { Class sfCertificatePanelClass = new Class ("SFCertificatePanel"); Selector sharedCertificatePanelSelector = new Selector ("sharedCertificatePanel"); // + (SFCertificatePanel *)sharedCertificatePanel; IntPtr panel = IntPtr_objc_msgSend (sfCertificatePanelClass.Handle, sharedCertificatePanelSelector.Handle); using (var sc = new SecCertificate (cert)) { NSArray a = NSArray.FromNSObjects (sc); //- (NSInteger)runModalForCertificates:(NSArray *)certificates showGroup:(BOOL)showGroup; //nint_objc_msgSend_IntPtr_bool (panel, Selector.GetHandle ("runModalForCertificates:showGroup:"), a.Handle, false); // - (void)beginSheetForWindow:(NSWindow *)docWindow modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo certificates:(NSArray *)certificates showGroup:(BOOL)showGroup; void_objc_msgSend_IntPtr_IntPtr_IntPtr_IntPtr_bool (panel, Selector.GetHandle ("beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:certificates:showGroup:"), NSApplication.SharedApplication.MainWindow.Handle, sender.Handle, Selector.GetHandle ("createPanelDidEnd:returnCode:contextInfo:"), IntPtr.Zero, a.Handle, false); } }
public static SecIdentity GetIdentity(X509Certificate certificate) { /* * If we got an 'X509Certificate2', then we require it to have a private key * and import it. */ var certificate2 = certificate as X509Certificate2; if (certificate2 != null) { return(SecIdentity.Import(certificate2)); } /* * Otherwise, we require the private key to be in the keychain. */ using (var secCert = new SecCertificate(certificate)) { return(SecKeyChain.FindIdentity(secCert, true)); } }
public void MailX1() { using (var cert = new X509Certificate(mail_google_com)) { /* * This X509Certificate constructor will use SecCertificateCreateWithData() and * store the SecCertificateRef in its Handle. */ Assert.That(cert.Handle, Is.Not.EqualTo(IntPtr.Zero), "Handle"); Assert.That(CFGetRetainCount(cert.Handle), Is.EqualTo((nint)1), "RetainCount"); using (var sc = new SecCertificate(cert)) { #if NET // dotnet PAL layer does not return the same instance CheckMailGoogleCom(sc, 1); // so the new one is RC == 1 #else Assert.That(sc.Handle, Is.EqualTo(cert.Handle), "Same Handle"); CheckMailGoogleCom(sc, 2); // same handle means another reference was added #endif Assert.That(cert.ToString(true), Is.EqualTo(sc.ToX509Certificate().ToString(true)), "X509Certificate"); } } }
public void Trust_FullChain() { X509CertificateCollection certs = new X509CertificateCollection(); certs.Add(new X509Certificate(CertificateTest.mail_google_com)); certs.Add(new X509Certificate(CertificateTest.thawte_sgc_ca)); certs.Add(new X509Certificate(CertificateTest.verisign_class3_root)); using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com")) using (var trust = new SecTrust(certs, policy)) { // that certificate stopped being valid on September 30th, 2013 so we validate it with a date earlier than that trust.SetVerifyDate(new DateTime(635108745218945450, DateTimeKind.Utc)); SecTrustResult trust_result = SecTrustResult.Unspecified; var ios9 = TestRuntime.CheckXcodeVersion(7, 0); var ios10 = TestRuntime.CheckXcodeVersion(8, 0); var ios11 = TestRuntime.CheckXcodeVersion(9, 0); if (ios10) { trust_result = SecTrustResult.FatalTrustFailure; } // iOS9 is not fully happy with the basic constraints: `SecTrustEvaluate [root AnchorTrusted BasicContraints]` else if (ios9) { trust_result = SecTrustResult.RecoverableTrustFailure; } var result = Evaluate(trust, true); Assert.That(result, Is.EqualTo(trust_result), "Evaluate"); // Evalute must be called prior to Count (Apple documentation) Assert.That(trust.Count, Is.EqualTo(3), "Count"); using (SecCertificate sc1 = trust [0]) { // seems the leaf gets an extra one Assert.That(CFGetRetainCount(sc1.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc1)"); Assert.That(sc1.SubjectSummary, Is.EqualTo("mail.google.com"), "SubjectSummary(sc1)"); } using (SecCertificate sc2 = trust [1]) { Assert.That(CFGetRetainCount(sc2.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc2)"); Assert.That(sc2.SubjectSummary, Is.EqualTo("Thawte SGC CA"), "SubjectSummary(sc2)"); } using (SecCertificate sc3 = trust [2]) { Assert.That(CFGetRetainCount(sc3.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc3)"); Assert.That(sc3.SubjectSummary, Is.EqualTo("Class 3 Public Primary Certification Authority"), "SubjectSummary(sc3)"); } if (TestRuntime.CheckXcodeVersion(5, 0)) { Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult"); trust.SetAnchorCertificates(certs); Assert.That(trust.GetCustomAnchorCertificates().Length, Is.EqualTo(certs.Count), "GetCustomAnchorCertificates"); if (ios11) { trust_result = SecTrustResult.Unspecified; } else { trust_result = SecTrustResult.Invalid; } // since we modified the `trust` instance it's result was invalidated (marked as unspecified on iOS 11) Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult-2"); } } }
public void MailRaw() { using (var sc = new SecCertificate(mail_google_com)) { CheckMailGoogleCom(sc, 1); } }
public X509Certificate GetAppleCertificate(X509Certificate certificate) { // This will remove the private key if we have any. using (var appleCert = new SecCertificate(certificate)) return(appleCert.ToX509Certificate()); }
void Trust_FullChain(SecTrust trust, SecPolicy policy, X509CertificateCollection certs) { // that certificate stopped being valid on September 30th, 2013 so we validate it with a date earlier than that trust.SetVerifyDate(new DateTime(635108745218945450, DateTimeKind.Utc)); SecTrustResult trust_result = SecTrustResult.Unspecified; var ios9 = TestRuntime.CheckXcodeVersion(7, 0); var ios10 = TestRuntime.CheckXcodeVersion(8, 0); var ios11 = TestRuntime.CheckXcodeVersion(9, 0); var ios13 = TestRuntime.CheckXcodeVersion(11, 0); if (ios10) { trust_result = SecTrustResult.FatalTrustFailure; } // iOS9 is not fully happy with the basic constraints: `SecTrustEvaluate [root AnchorTrusted BasicContraints]` else if (ios9) { trust_result = SecTrustResult.RecoverableTrustFailure; } var result = Evaluate(trust, true); Assert.That(result, Is.EqualTo(trust_result), "Evaluate"); // Evalute must be called prior to Count (Apple documentation) Assert.That(trust.Count, Is.EqualTo(3), "Count"); using (SecCertificate sc1 = trust [0]) { // seems the leaf gets an extra one Assert.That(CFGetRetainCount(sc1.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc1)"); Assert.That(sc1.SubjectSummary, Is.EqualTo("mail.google.com"), "SubjectSummary(sc1)"); } using (SecCertificate sc2 = trust [1]) { Assert.That(CFGetRetainCount(sc2.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc2)"); Assert.That(sc2.SubjectSummary, Is.EqualTo("Thawte SGC CA"), "SubjectSummary(sc2)"); } using (SecCertificate sc3 = trust [2]) { Assert.That(CFGetRetainCount(sc3.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc3)"); Assert.That(sc3.SubjectSummary, Is.EqualTo("Class 3 Public Primary Certification Authority"), "SubjectSummary(sc3)"); } if (TestRuntime.CheckXcodeVersion(5, 0)) { Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult"); trust.SetAnchorCertificates(certs); Assert.That(trust.GetCustomAnchorCertificates().Length, Is.EqualTo(certs.Count), "GetCustomAnchorCertificates"); #if __MACOS__ if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 15)) { trust_result = SecTrustResult.RecoverableTrustFailure; } else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13)) { trust_result = SecTrustResult.Unspecified; } else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 12)) { trust_result = SecTrustResult.Invalid; } else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 11)) { trust_result = SecTrustResult.RecoverableTrustFailure; } else { trust_result = SecTrustResult.Unspecified; } #else if (ios13) { trust_result = SecTrustResult.RecoverableTrustFailure; } else if (ios11) { trust_result = SecTrustResult.Unspecified; } else { trust_result = SecTrustResult.Invalid; } #endif // since we modified the `trust` instance it's result was invalidated (marked as unspecified on iOS 11) Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult-2"); } if (TestRuntime.CheckXcodeVersion(12, 0)) { // old certificate (built in our tests) was not quite up to spec and it eventually became important Assert.False(trust.Evaluate(out var error), "Evaluate"); Assert.NotNull(error, "error"); Assert.That(error.LocalizedDescription, Is.EqualTo("“mail.google.com” certificate is not standards compliant"), "desc"); } else if (TestRuntime.CheckXcodeVersion(11, 0)) { Assert.False(trust.Evaluate(out var error), "Evaluate"); Assert.NotNull(error, "error"); Assert.That(error.LocalizedDescription, Does.Contain("\"mail.google.com\",\"Thawte SGC CA\",\"Class 3 Public Primary Certification Authority\" certificates do not meet pinning requirements")); var underlyingError = (NSError)error.UserInfo [NSError.UnderlyingErrorKey]; // Error is: // Certificate 0 “mail.google.com” has errors: Key size is not permitted for this use, SSL hostname does not match name(s) in certificate, Signature hash algorithm is not permitted for this use;Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use;Certificate 2 “Class 3 Public Primary Certification Authority” has errors: Key size is not permitted for this use; // But the exact format can vary // watchOS reports this: // Certificate 0 “mail.google.com” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use, SSL hostname does not match name(s) in certificate;Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use;Certificate 2 “Class 3 Public Primary Certification Authority” has errors: Key size is not permitted for this use; Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 0 “mail.google.com” has errors: ")); Assert.That(underlyingError.LocalizedDescription, Does.Contain("Key size is not permitted for this use")); Assert.That(underlyingError.LocalizedDescription, Does.Contain("SSL hostname does not match name(s) in certificate").Or.Contain("Signature hash algorithm is not permitted for this use")); Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use")); Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 2 “Class 3 Public Primary Certification Authority” has errors:")); } else if (TestRuntime.CheckXcodeVersion(10, 0)) { Assert.True(trust.Evaluate(out var error), "Evaluate"); Assert.Null(error, "error"); } }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) { NetworkCredential credentialsToUse; if (This.Credentials != null) { if (This.Credentials is NetworkCredential) { credentialsToUse = (NetworkCredential)This.Credentials; } else { var uri = this.getResponseForTask(task).Request.RequestUri; credentialsToUse = This.Credentials.GetCredential(uri, "NTLM"); } var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } return; } if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate) { Console.WriteLine("Client Cert!"); var password = "******"; var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase); var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12"); var certData = File.ReadAllBytes(path); NSDictionary[] importResult; X509Certificate cert = new X509Certificate(certData, password); SecStatusCode statusCode = SecImportExport.ImportPkcs12(certData, options, out importResult); var identityHandle = importResult[0][SecImportExport.Identity]; var identity = new SecIdentity(identityHandle.Handle); var certificate = new SecCertificate(cert.GetRawCertData()); SecCertificate[] certificates = { certificate }; NSUrlCredential credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); return; } if (!This.customSSLVerification) { goto doDefault; } if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust") { goto doDefault; } if (ServicePointManager.ServerCertificateValidationCallback == null) { goto doDefault; } // Convert Mono Certificates to .NET certificates and build cert // chain from root certificate var serverCertChain = challenge.ProtectionSpace.ServerSecTrust; var chain = new X509Chain(); X509Certificate2 root = null; var errors = SslPolicyErrors.None; if (serverCertChain == null || serverCertChain.Count == 0) { errors = SslPolicyErrors.RemoteCertificateNotAvailable; goto sslErrorVerify; } if (serverCertChain.Count == 1) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var netCerts = Enumerable.Range(0, serverCertChain.Count) .Select(x => serverCertChain[x].ToX509Certificate2()) .ToArray(); for (int i = 1; i < netCerts.Length; i++) { chain.ChainPolicy.ExtraStore.Add(netCerts[i]); } root = netCerts[0]; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; if (!chain.Build(root)) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; goto sslErrorVerify; } sslErrorVerify: var hostname = task.CurrentRequest.Url.Host; bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors); if (result) { completionHandler( NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust)); } else { completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; doDefault: completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); return; }
void LookupCert() { var rec = new SecRecord(SecKind.Certificate) { Label = labelText }; SecStatusCode rc; var rec2 = SecKeyChain.QueryAsRecord(rec, out rc); if (rc == SecStatusCode.Success) { Console.WriteLine (rec2.Label); Console.WriteLine (rec2.ValueData); SecCertificate cert = new SecCertificate (rec2.ValueData); } else { Console.WriteLine (rc); } }
public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler) { if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) { NetworkCredential credentialsToUse; if (This.Credentials != null) { if (This.Credentials is NetworkCredential) { credentialsToUse = (NetworkCredential)This.Credentials; } else { var uri = this.getResponseForTask(task).Request.RequestUri; credentialsToUse = This.Credentials.GetCredential(uri, "NTLM"); } var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); } return; } if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate) { Console.WriteLine("Client Cert!"); var password = "******"; var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase); var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12"); var certData = File.ReadAllBytes(path); NSDictionary[] importResult; X509Certificate cert = new X509Certificate(certData, password); SecStatusCode statusCode = SecImportExport.ImportPkcs12(certData, options, out importResult); var identityHandle = importResult[0][SecImportExport.Identity]; var identity = new SecIdentity(identityHandle.Handle); var certificate = new SecCertificate(cert.GetRawCertData()); SecCertificate[] certificates = { certificate }; NSUrlCredential credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession); completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential); return; } if (!This.customSSLVerification) { goto doDefault; } if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust") { goto doDefault; } if (ServicePointManager.ServerCertificateValidationCallback == null) { goto doDefault; } // Convert Mono Certificates to .NET certificates and build cert // chain from root certificate var serverCertChain = challenge.ProtectionSpace.ServerSecTrust; var chain = new X509Chain(); X509Certificate2 root = null; var errors = SslPolicyErrors.None; if (serverCertChain == null || serverCertChain.Count == 0) { errors = SslPolicyErrors.RemoteCertificateNotAvailable; goto sslErrorVerify; } if (serverCertChain.Count == 1) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var netCerts = Enumerable.Range(0, serverCertChain.Count) .Select(x => serverCertChain[x].ToX509Certificate2()) .ToArray(); for (int i = 1; i < netCerts.Length; i++) { chain.ChainPolicy.ExtraStore.Add(netCerts[i]); } root = netCerts[0]; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; if (!chain.Build(root)) { errors = SslPolicyErrors.RemoteCertificateChainErrors; goto sslErrorVerify; } var subject = root.Subject; var subjectCn = cnRegex.Match(subject).Groups[1].Value; if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) { errors = SslPolicyErrors.RemoteCertificateNameMismatch; goto sslErrorVerify; } sslErrorVerify: var hostname = task.CurrentRequest.Url.Host; bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors); if (result) { completionHandler( NSUrlSessionAuthChallengeDisposition.UseCredential, NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust)); } else { completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null); } return; doDefault: completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential); return; }