using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml; using System.Xml.XPath; using System.Text; using System.Net; using System.Net.Security; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService, IProtectionOrderPortBinding { private ClientCertStatus clientCertStatus; private StringBuilder sb; private enum ClientCertStatus { NOERRORS, TIMEERROR, NOTTRUSTED, CNNOTMATCH, NOTPRESENT }; public Service() { //Uncomment the following line if using designed components //InitializeComponent(); } private ClientCertStatus ValidateClientCert() { HttpClientCertificate cert = Context.Request.ClientCertificate; #region VerboseDebugging if (cert != null) sb = new StringBuilder(); DateTime dtNow = DateTime.Now; sb.Append("Client Certificate Received:\t"); sb.Append(dtNow.ToString("yyyy-MM-dd hh:mm:ss tt")); sb.Append(Environment.NewLine); sb.Append("IsPresent:\t"); sb.Append(cert.IsPresent); sb.Append(Environment.NewLine); sb.Append("Encoding:\t"); sb.Append(cert.CertEncoding); sb.Append(Environment.NewLine); sb.Append("Issuer:\t"); sb.Append(cert.Issuer); sb.Append(Environment.NewLine); //The client certificate is not valid if the Certificate //Authority (CA) is not in the list of recognized CAs on the server. sb.Append("IsValid:\t"); sb.Append(cert.IsValid); sb.Append(Environment.NewLine); sb.Append("SerialNumber:\t"); sb.Append(cert.SerialNumber); sb.Append(Environment.NewLine); sb.Append("ServerIssuer:\t"); sb.Append(cert.ServerIssuer); sb.Append(Environment.NewLine); sb.Append("ServerSubject:\t"); sb.Append(cert.ServerSubject); sb.Append(Environment.NewLine); sb.Append("Subject:\t"); sb.Append(cert.Subject); sb.Append(Environment.NewLine); sb.Append("ValidFrom:\t"); sb.Append(cert.ValidFrom.ToString("yyyy-MM-dd hh:mm:ss tt")); sb.Append(Environment.NewLine); sb.Append("ValidUntil:\t"); sb.Append(cert.ValidUntil.ToString("yyyy-MM-dd hh:mm:ss tt")); sb.Append(Environment.NewLine); #endregion #region Check to see that cert is present if (!cert.IsPresent) { return ClientCertStatus.NOTPRESENT; } #endregion #region Check to see that cert is valid, trusted ca if (!cert.IsValid) { return ClientCertStatus.NOTTRUSTED; } #endregion #region Check to see that cert is from a machine that we actually trust if (cert.Subject.Contains("CN=labdc.doa.wistate.us") || cert.Subject.Contains("CN=wijis.wisconsin.gov") || cert.Subject.Contains("CN=wijisgwtest.wisconsin.gov")) { } else { ApplicationEventLog.WriteError(cert.Subject + Environment.NewLine + "Attempted to access the service and is not allowed to do so." + Environment.NewLine); return ClientCertStatus.CNNOTMATCH; //TODO: Eventually you probably want to throw an exception here to prevent //anyone with a certificate that you are not expecting to not get access to the service //throw new Exception("Invalid Certificate"); } #endregion #region Check to see that cert is within the valid time window if (DateTime.Now > cert.ValidUntil || DateTime.Now < cert.ValidFrom) { return ClientCertStatus.TIMEERROR; } #endregion return ClientCertStatus.NOERRORS; } [WebMethod] public XmlDocument submit(object thisObject) { XmlNode[] thisNode = thisObject as XmlNode[]; XmlNode headNode = thisNode[1]; String innerXML = headNode.InnerXml; // Create an XmlNamespaceManager to resolve the default namespace. XmlNamespaceManager nsmgr = new XmlNamespaceManager(headNode.OwnerDocument.NameTable); nsmgr.AddNamespace("doc", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/document/"); nsmgr.AddNamespace("j", "http://www.it.ojp.gov/jxdm/3.0.3"); nsmgr.AddNamespace("protection-order", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); this.clientCertStatus = ValidateClientCert(); if (this.clientCertStatus.Equals(ClientCertStatus.NOERRORS)) //if(true) { #region Get Element values string elementsInInvocation = HelperMethods.getElementValues(headNode, nsmgr); #endregion XmlDocument responseDoc = this.createResponseDocument(headNode, nsmgr); return responseDoc; } else { throw new Exception("The cert is not valid: " + this.clientCertStatus); } } private XmlDocument createResponseDocument(XmlNode submissionDocumentNode, XmlNamespaceManager nsmgr) { XmlDocument responseDoc = new XmlDocument(); XmlElement rootElement = responseDoc.CreateElement("doc:ProtectionOrderResponseDocument", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/document/"); rootElement.SetAttribute("xmlns:doc", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/document/"); rootElement.SetAttribute("xmlns:j", "http://www.it.ojp.gov/jxdm/3.0.3"); rootElement.SetAttribute("xmlns:protection-order", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); rootElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); rootElement.SetAttribute("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/document/../ProtectionOrderResponse/ProtectionOrderResponse.xsd"); string docId = submissionDocumentNode.SelectSingleNode("./@j:id", nsmgr).InnerText; rootElement.SetAttribute("id", "http://www.it.ojp.gov/jxdm/3.0.3", docId); responseDoc.AppendChild(rootElement); // PODescriptiveMetadata XmlElement poDesciptiveMetadata = responseDoc.CreateElement("protection-order:ProtectionOrderDescriptiveMetadata", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); XmlElement documentReceiveDate = responseDoc.CreateElement("j:DocumentReceivedDate", "http://www.it.ojp.gov/jxdm/3.0.3"); documentReceiveDate.InnerText = DateTime.Now.ToString("yyyy-MM-dd"); poDesciptiveMetadata.AppendChild(documentReceiveDate); XmlElement documentReceivedTime = responseDoc.CreateElement("protection-order:DocumentReceivedTime", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); documentReceivedTime.InnerText = DateTime.Now.ToString("hh:MM:ss"); poDesciptiveMetadata.AppendChild(documentReceivedTime); rootElement.AppendChild(poDesciptiveMetadata); // ProtectionOrder XmlNode poNode = submissionDocumentNode.SelectSingleNode("./protection-order:ProtectionOrder", nsmgr); string poId = poNode.SelectSingleNode("./@j:id", nsmgr).InnerText; XmlElement poElement = responseDoc.CreateElement("protection-order:ProtectionOrder", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); poElement.SetAttribute("id", "http://www.it.ojp.gov/jxdm/3.0.3", poId); rootElement.AppendChild(poElement); XmlNode courtOrderDesignatedLocation = poNode.SelectSingleNode("./j:CourtOrderDesignatedLocation", nsmgr); poElement.AppendChild(responseDoc.ImportNode(courtOrderDesignatedLocation, true)); XmlNode caseNode = poNode.SelectSingleNode("./j:Case", nsmgr); poElement.AppendChild(responseDoc.ImportNode(caseNode, true)); XmlElement poSubject = responseDoc.CreateElement("protection-order:ProtectionOrderSubject", "http://wijis.wisconsin.gov/specs/schemas/court-docs/protection-order/v1.2/2008-06-23/extension/"); poElement.AppendChild(poSubject); XmlNode subjectName = poNode.SelectSingleNode("./protection-order:ProtectionOrderSubject/j:PersonName", nsmgr); poSubject.AppendChild(responseDoc.ImportNode(subjectName, true)); XmlNode subjectBirthDate = poNode.SelectSingleNode("./protection-order:ProtectionOrderSubject/j:PersonBirthDate", nsmgr); poSubject.AppendChild(responseDoc.ImportNode(subjectBirthDate, true)); XmlNode subjectId = poNode.SelectSingleNode("./protection-order:ProtectionOrderSubject/@j:id", nsmgr); if (subjectId != null) { poSubject.SetAttribute("id", "http://www.it.ojp.gov/jxdm/3.0.3", subjectId.InnerText); } return responseDoc; } [WebMethod] public NotificationResponseType notify(object thisObject) { return null; } }