protected SslHandshakeStatus ProcessCertificateRequest(HandshakeMessage message) { if (m_State == HandshakeType.ServerKeyExchange) { CipherDefinition cd = CipherSuites.GetCipherDefinition(m_EncryptionScheme); if (this.m_RemoteCertificate.GetPublicKeyLength() <= 512 || !cd.Exportable) throw new SslException(AlertDescription.HandshakeFailure, "Invalid message."); } else if (m_State != HandshakeType.Certificate) { throw new SslException(AlertDescription.UnexpectedMessage, "CertificateRequest message must be preceded by a Certificate or ServerKeyExchange message."); } UpdateHashes(message, HashUpdate.All); // input message // get supported certificate types bool supportsRsaCerts = false; byte[] certTypes = new byte[message.fragment[0]]; // currently we're not doing anything with the supported certificate types Buffer.BlockCopy(message.fragment, 1, certTypes, 0, certTypes.Length); for(int i = 0; i < certTypes.Length; i++) { if (certTypes[i] == 1) { // rsa_sign supportsRsaCerts = true; break; } } // get list of distinguished names if (m_Options.RequestHandler != null && supportsRsaCerts) { // make sure the client passed a delegate Queue q = new Queue(); DistinguishedNameList r = new DistinguishedNameList(); int size, offset = message.fragment[0] + 3; byte[] buffer; while(offset < message.fragment.Length) { size = message.fragment[offset] * 256 + message.fragment[offset + 1]; buffer = new byte[size]; Buffer.BlockCopy(message.fragment, offset + 2, buffer, 0, size); q.Enqueue(buffer); offset += size + 2; } // decode RDN structures while(q.Count > 0) { r.Add(ProcessName((byte[])q.Dequeue())); } RequestEventArgs e = new RequestEventArgs(); try { m_Options.RequestHandler(Parent, r, e); if (e.Certificate != null) m_Options.Certificate = e.Certificate; } catch (Exception de) { throw new SslException(de, AlertDescription.InternalError, "The code in the CertRequestEventHandler delegate threw an error."); } } if (!supportsRsaCerts) m_Options.Certificate = null; // do not send client certificate m_MutualAuthentication = true; return new SslHandshakeStatus(SslStatus.MessageIncomplete, null); }
private void GetClientCertAtClient(SecureSocket socket, DistinguishedNameList acceptable, RequestEventArgs e) { Debug.WriteLine("server requested client certificate"); e.Certificate = m_clientAuth.GetClientCertificate(acceptable); }
private bool IsDistinguishedNameInList(DistinguishedName searchFor, DistinguishedNameList acceptable) { foreach (DistinguishedName acceptableName in acceptable) { if (IsNamePartOfOtherName(searchFor, acceptableName)) { return true; } } return false; }
/// <summary> /// see <see cref="Ch.Elca.Iiop.Security.Ssl.IClientSideAuthentication.GetClientCertificate"/> /// </summary> public override Certificate GetClientCertificate(DistinguishedNameList acceptable) { CertificateStore store = new CertificateStore(m_storeLocation, MY_STORE_NAME); Certificate toCheck = store.FindCertificate(); while(toCheck != null) { if ((toCheck.IsCurrent) && IsClientCertificate(toCheck)) { // check, if the root certificate in the chain is known by the server, if yes // -> server will be able to verify the certificate chain Certificate[] chain = toCheck.GetCertificateChain().GetCertificates(); if (chain.Length >= 1) { // last certificate in the chain is the root certificate if (IsDistinguishedNameInList(chain[chain.Length - 1].GetDistinguishedName(), acceptable)) { return toCheck; } } } toCheck = store.FindCertificate(toCheck); } return null; }
/// <summary> /// see <see cref="Ch.Elca.Iiop.Security.Ssl.IClientSideAuthentication.GetClientCertificate"/> /// </summary> public override Certificate GetClientCertificate(DistinguishedNameList acceptable) { return m_clientCertificate; }
/// <summary> /// see <see cref="Ch.Elca.Iiop.Security.Ssl.IClientSideAuthentication.GetClientCertificate"/> /// </summary> public virtual Certificate GetClientCertificate(DistinguishedNameList acceptable) { return null; }