/// <summary> /// Herunterladen der Zertifikat-Liste /// </summary> /// <param name="list">Zertifikat-Liste die zu Laden ist</param> /// <returns>Zertifikat-Liste</returns> public async Task <IReadOnlyList <X509Certificate> > DownloadCertificateListAsync(OstcListeListe list) { var query = new OstcListe { Liste = list }; var queryData = OstcUtils.Serialize(query, Encoding.UTF8); ValidateData(queryData, OstcMessageType.ListData); var now = DateTime.Now; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, DateTimeKind.Local).ToUniversalTime(); var message = new TransportRequestType() { version = SupportedVersionsType.Item11, profile = ExtraProfileOstc, TransportHeader = CreateRequestHeader(now, OstcDataType.ListRequest, ExtraScenario.RequestWithResponse), TransportBody = new TransportRequestBodyType { Items = new object[] { new DataType { Item = new Base64CharSequenceType() { Value = queryData, }, }, }, }, }; ValidateRequest(message, OstcMessageType.List); var messageData = OstcExtraSerializer.Utf8.Serialize(message); var request = CreateRequest(Network.Requests.ListRequest); using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null)) { requestStream.Write(messageData, 0, messageData.Length); } using (var response = await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)) { var serializer = new XmlSerializer(typeof(TransportResponseType)); var responseData = (TransportResponseType)serializer.Deserialize(response.GetResponseStream()); var flags = responseData.TransportHeader.GetFlags().ToList(); if (flags.Any(x => x.weight == ExtraFlagWeight.Error)) { throw new Ostc2Exception(flags); } var data = ((Base64CharSequenceType)((DataType)responseData.TransportBody.Items[0]).Item).Value; var result = OstcUtils.ReadCertificates(new MemoryStream(data)); return(result); } }
/// <summary> /// Bestätigung des Auftrags /// </summary> /// <param name="orderId">ID des Auftrags</param> /// <param name="hash">Hash des öffentlichen Schlüssels</param> /// <returns></returns> public async Task AcknowledgeOrderAsync(string orderId, byte[] hash) { var query = new OstcAuftrag { Auftragsnummer = orderId, hash = string.Join(string.Empty, hash.Select(x => x.ToString("X2"))), ItemElementName = (CompanyNumberType)Enum.Parse(typeof(CompanyNumberType), Sender.SenderId.Type.ToString()), Item = Sender.SenderId.Id, }; var queryData = OstcUtils.Serialize(query, Iso88591); ValidateData(queryData, OstcMessageType.OrderData); var now = DateTime.Now; var message = new TransportRequestType() { version = SupportedVersionsType.Item11, profile = ExtraProfileOstc, TransportHeader = CreateRequestHeader(now, OstcDataType.Order, ExtraScenario.RequestWithAcknowledgement), TransportBody = new TransportRequestBodyType { Items = new object[] { new DataType { Item = new Base64CharSequenceType() { Value = queryData, }, }, }, }, }; ValidateRequest(message, OstcMessageType.Order); var messageData = OstcExtraSerializer.Iso88591.Serialize(message); var request = CreateRequest(Network.Requests.Order); using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null)) { requestStream.Write(messageData, 0, messageData.Length); } using (var response = await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)) { var serializer = new XmlSerializer(typeof(TransportResponseType)); var responseData = (TransportResponseType)serializer.Deserialize(response.GetResponseStream()); var flags = responseData.TransportHeader.GetFlags().ToList(); if (flags.Any(x => x.weight == ExtraFlagWeight.Error)) { throw new Ostc2Exception(flags); } } }
private XDocument CreateAcknowledge(string requestId, DateTime requestTimestamp, params string[] responseIds) { var extra = new TransportRequestType() { version = SupportedVersionsType.Item14, profile = "http://www.extra-standard.de/profile/DEUEV/2.0", TransportHeader = new TransportRequestHeaderType() { Sender = new SenderType() { SenderID = new ClassifiableIDType() { Value = _sender.Betriebsnummer }, }, Receiver = new ReceiverType() { ReceiverID = new ClassifiableIDType() { Value = DsrvConstants.Betriebsnummer }, }, RequestDetails = new RequestDetailsType() { RequestID = new ClassifiableIDType() { Value = requestId, }, TimeStamp = requestTimestamp.ToUniversalTime(), TimeStampSpecified = true, Application = new ApplicationType() { Manufacturer = "DATALINE GmbH & Co. KG", Product = new TextType() { Value = "DATALINE Lohnabzug" }, }, Procedure = DsrvConstants.ProcedureAcknowledge, DataType = ExtraStandard.ExtraDataType.ConfirmationOfReceipt, Scenario = ExtraScenario.RequestWithAcknowledgement, }, }, TransportBody = new TransportRequestBodyType() { Items = new object[] { new DataType1() { Item = new ElementSequenceType() { Any = new object[] { new ConfirmationOfReceiptType() { version = ConfirmationOfReceiptTypeVersion.Item13, PropertySet = new PropertySetType() { name = ExtraPropertySetName.ResponseID, Value = responseIds .Select(x => new ExtraStandard.Extra14.ValueType() { Value = x, }).ToArray(), }, }, }, }, }, }, }, }; var ns = new XmlSerializerNamespaces(); ns.Add("xreq", "http://www.extra-standard.de/namespace/request/1"); ns.Add("xcpt", "http://www.extra-standard.de/namespace/components/1"); ns.Add("xplg", "http://www.extra-standard.de/namespace/plugins/1"); ns.Add("xmsg", "http://www.extra-standard.de/namespace/message/1"); var serializer = ExtraStandard.ExtraUtilities.GetSerializer <TransportRequestType>(); var output = new MemoryStream(); using (var writer = new StreamWriter(output) { AutoFlush = true }) { serializer.Serialize(writer, extra, ns); } var serialized = output.ToArray(); var document = XDocument.Load(new MemoryStream(serialized)); var validator = _validatorFactory.Create(ExtraMessageType.AcknowledgeProcessingResult, ExtraTransportDirection.Request, false); validator.Validate(document); return(document); }
private XDocument CreateQuery(string requestId, DateTime requestTimestamp, string acceptResponseId) { var extra = new TransportRequestType() { version = SupportedVersionsType.Item14, profile = "http://www.extra-standard.de/profile/DEUEV/2.0", TransportHeader = new TransportRequestHeaderType() { Sender = new SenderType() { SenderID = new ClassifiableIDType() { Value = _sender.Betriebsnummer }, }, Receiver = new ReceiverType() { ReceiverID = new ClassifiableIDType() { Value = DsrvConstants.Betriebsnummer }, }, RequestDetails = new RequestDetailsType() { RequestID = new ClassifiableIDType() { Value = requestId, }, TimeStamp = requestTimestamp.ToUniversalTime(), TimeStampSpecified = true, Application = new ApplicationType() { Manufacturer = "DATALINE GmbH & Co. KG", Product = new TextType() { Value = "DATALINE Lohnabzug" }, }, Procedure = DsrvConstants.ProcedureQuery, DataType = ExtraStandard.ExtraDataType.DataRequest, Scenario = ExtraScenario.RequestWithResponse, }, }, TransportBody = new TransportRequestBodyType() { Items = new object[] { new DataType1() { Item = new ElementSequenceType() { Any = new object[] { new DataRequestType() { Query = new[] { new DataRequestArgumentType() { property = ExtraStatusRequestPropertyName.ResponseID, type = XSDPrefixedTypeCodes1.xsstring, @event = EventNamesType.httpwwwextrastandarddeeventSendData, Items = new object[] { new OperandType() { Value = acceptResponseId }, }, ItemsElementName = new[] { ItemsChoiceType4.GT, }, }, new DataRequestArgumentType() { property = ExtraStatusRequestPropertyName.Procedure, Items = new object[] { new OperandType() { Value = "DSV" }, }, ItemsElementName = new[] { ItemsChoiceType4.EQ, }, }, }, }, }, }, }, }, }, }; var ns = new XmlSerializerNamespaces(); ns.Add("xreq", "http://www.extra-standard.de/namespace/request/1"); ns.Add("xcpt", "http://www.extra-standard.de/namespace/components/1"); ns.Add("xplg", "http://www.extra-standard.de/namespace/plugins/1"); ns.Add("xmsg", "http://www.extra-standard.de/namespace/message/1"); var serializer = ExtraStandard.ExtraUtilities.GetSerializer <TransportRequestType>(); var output = new MemoryStream(); using (var writer = new StreamWriter(output) { AutoFlush = true }) { serializer.Serialize(writer, extra, ns); } var serialized = output.ToArray(); var document = XDocument.Load(new MemoryStream(serialized)); var validator = _validatorFactory.Create(ExtraMessageType.GetProcessingResult, ExtraTransportDirection.Request, false); validator.Validate(document); return(document); }
private XDocument CreateDelivery(string requestId, DateTime requestTimestamp, int fileNumber, string data) { var encodingId = "I1"; var encoding = ExtraEncodingFactory.Dsrv.GetEncoding(encodingId); var requestData = encoding.GetBytes(data); var dataName = $"{(_isTest ? 'T' : 'E')}DSV0{fileNumber:D6}"; var dataTransformsHelper = new ExtraDataTransformHandler(new[] { _compressionHandler }, new[] { _encryptionHandler }); var transformResult = dataTransformsHelper.Transform(requestData, dataName, requestTimestamp, _compressionHandler.AlgorithmId, _encryptionHandler.AlgorithmId); var requestDataEncrypted = transformResult.Item1; var extra = new TransportRequestType() { version = SupportedVersionsType.Item14, profile = "http://www.extra-standard.de/profile/DEUEV/2.0", TransportHeader = new TransportRequestHeaderType() { Sender = new SenderType() { SenderID = new ClassifiableIDType() { Value = _sender.Betriebsnummer }, }, Receiver = new ReceiverType() { ReceiverID = new ClassifiableIDType() { Value = DsrvConstants.Betriebsnummer }, }, RequestDetails = new RequestDetailsType() { RequestID = new ClassifiableIDType() { Value = requestId, }, TimeStamp = requestTimestamp.ToUniversalTime(), TimeStampSpecified = true, Application = new ApplicationType() { Manufacturer = "DATALINE GmbH & Co. KG", Product = new TextType() { Value = "DATALINE Lohnabzug" }, }, Procedure = DsrvConstants.ProcedureSend, DataType = ExtraDataType.VSNRAnfrage, Scenario = ExtraScenario.RequestWithAcknowledgement, }, }, TransportPlugIns = new AnyPlugInContainerType() { Any = new object[] { new DataTransformsType() { version = DataTransformsTypeVersion.Item12, versionSpecified = true, Compression = transformResult.Item2.OfType <CompressionType>().ToArray(), Encryption = transformResult.Item2.OfType <EncryptionType>().ToArray(), }, new DataSourceType() { version = DataSourceTypeVersion.Item10, versionSpecified = true, DataContainer = new DataContainerType() { type = ExtraContainerType.File, created = requestTimestamp.ToUniversalTime(), createdSpecified = true, encoding = encodingId, name = dataName, }, }, new ContactsType() { version = ContactsTypeVersion.Item10, versionSpecified = true, SenderContact = new[] { new ContactType() { Endpoint = new[] { new EndpointType() { type = EndpointTypeType.SMTP, Value = _sender.Email, }, }, }, }, }, }, }, TransportBody = new TransportRequestBodyType() { Items = new object[] { new DataType1() { Item = new Base64CharSequenceType() { Value = requestDataEncrypted, }, }, }, }, }; var ns = new XmlSerializerNamespaces(); ns.Add("xreq", "http://www.extra-standard.de/namespace/request/1"); ns.Add("xcpt", "http://www.extra-standard.de/namespace/components/1"); ns.Add("xplg", "http://www.extra-standard.de/namespace/plugins/1"); var serializer = ExtraStandard.ExtraUtilities.GetSerializer <TransportRequestType>(); var output = new MemoryStream(); using (var writer = new StreamWriter(output)) { serializer.Serialize(writer, extra, ns); } var serialized = output.ToArray(); var document = XDocument.Load(new MemoryStream(serialized)); var validator = _validatorFactory.Create(ExtraMessageType.SupplyData, ExtraTransportDirection.Request, false); validator.Validate(document); return(document); }
/// <summary> /// Herunterladen des Zertifikats /// </summary> /// <param name="orderId">ID des Auftrags</param> /// <returns>Zertifikat von der OSTC (private Schlüssel fehlt hier!)</returns> /// <remarks>Es wird eine Exception ausgelöst, wenn noch kein Schlüssel verfügbar ist.</remarks> public async Task <IReadOnlyList <X509Certificate> > DownloadCertificateAsync(string orderId) { var query = new OstcSchluessel { Auftragsnummer = orderId, ItemElementName = (OstcKeyType)Enum.Parse(typeof(OstcKeyType), Sender.SenderId.Type.ToString()), Item = Sender.SenderId.Id, }; var queryData = OstcUtils.Serialize(query, Iso88591); ValidateData(queryData, OstcMessageType.KeyData); var now = DateTime.Now; var message = new TransportRequestType() { version = SupportedVersionsType.Item11, profile = ExtraProfileOstc, TransportHeader = CreateRequestHeader(now, OstcDataType.Key, ExtraScenario.RequestWithResponse), TransportBody = new TransportRequestBodyType { Items = new object[] { new DataType { Item = new Base64CharSequenceType() { Value = queryData, }, }, }, }, }; ValidateRequest(message, OstcMessageType.Key); var messageData = OstcExtraSerializer.Iso88591.Serialize(message); var request = CreateRequest(Network.Requests.KeyRequest); using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null)) { requestStream.Write(messageData, 0, messageData.Length); } using (var response = await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)) { var serializer = new XmlSerializer(typeof(TransportResponseType)); var responseData = (TransportResponseType)serializer.Deserialize(response.GetResponseStream()); var flags = responseData.TransportHeader.GetFlags().ToList(); if (flags.Any(x => x.weight == ExtraFlagWeight.Error)) { throw new Ostc2Exception(flags); } var certData = ((Base64CharSequenceType)((DataType)responseData.TransportBody.Items[0]).Item).Value; var parser = new X509CertificateParser(); var certs = parser.ReadCertificates(certData).Cast <X509Certificate>().ToList(); return(certs); } }
/// <summary> /// Antragstellung /// </summary> /// <param name="application">Antrag</param> /// <param name="certStore">Zertifikat-Speicher für die Ermittlung der Zertifikatskette des Absender-Zertifikats</param> /// <param name="pfx">Absender-Zertifikat für die Signierung des Antrags</param> /// <returns>Ergebnis der Antragstellung</returns> public async Task <OstcApplicationResult> SendApplicationAsync([NotNull] OstcAntrag application, [CanBeNull] IOstcCertificateStore certStore, [CanBeNull] Pkcs12Store pfx) { var now = DateTime.Now; application.Antragsteller.IK_BN = Sender.SenderId.ToString(); RsaPrivateCrtKeyParameters rsaPrivateKey; AsymmetricCipherKeyPair rsaKeyPair; X509Certificate certificate; if (pfx != null) { var alias = pfx.Aliases.Cast <string>().First(pfx.IsKeyEntry); rsaPrivateKey = (RsaPrivateCrtKeyParameters)pfx.GetKey(alias).Key; var rsaPublicKey = new RsaKeyParameters(false, rsaPrivateKey.Modulus, rsaPrivateKey.PublicExponent); rsaKeyPair = new AsymmetricCipherKeyPair(rsaPublicKey, rsaPrivateKey); certificate = pfx.GetCertificate(alias).Certificate; } else { var keyPairGen = new RsaKeyPairGenerator(); keyPairGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048)); rsaKeyPair = keyPairGen.GenerateKeyPair(); rsaPrivateKey = (RsaPrivateCrtKeyParameters)rsaKeyPair.Private; certificate = null; } var requester = new Requester(application.Antragsteller.IK_BN, application.Antragsteller.Firma, application.Antragsteller.Nachname); var p10Creator = new Pkcs10Creator(requester, rsaKeyPair); var p10Data = p10Creator.CreateRequest(); application.Antragsinfo.Requestschlüssel = p10Data.CertRequestDer; var applicationData = OstcUtils.Serialize(application, Iso88591); ValidateData(applicationData, OstcMessageType.ApplicationData); var receiver = Sender.SenderId.CommunicationServerReceiver; if (certificate != null) { Debug.Assert(certStore != null, "certStore != null"); var certChain = certStore.GetChain(certificate).ToList(); Debug.Assert(certChain[0].SubjectDN.Equivalent(certificate.SubjectDN)); certChain.RemoveAt(0); applicationData = OstcUtils.SignData(applicationData, rsaPrivateKey, certificate, certChain); var receiverCert = certStore.GetCertificate(receiver); applicationData = OstcUtils.EncryptData(applicationData, receiverCert); } var fileName = $"{application.Antragsteller.IK_BN}_{now.Date:ddMMyyyy}.xml"; var message = new TransportRequestType() { version = SupportedVersionsType.Item11, profile = ExtraProfileOstc, TransportHeader = CreateRequestHeader(now, OstcDataType.Application, ExtraScenario.RequestWithAcknowledgement), TransportBody = new TransportRequestBodyType { Items = new object[] { new DataType { Item = new Base64CharSequenceType() { Value = applicationData, }, }, }, }, }; if (certificate != null) { message.TransportPlugIns = new AnyPlugInContainerType { Items = new object[] { new DataTransformsType { version = "1.1", Encryption = new[] { new EncryptionType { order = "1", Algorithm = new EncryptionAlgorithmType { id = ExtraEncryption.Pkcs7, Specification = new SpecificationType { url = "http://www.gkv-datenaustausch.de", name = "Security-Schnittstelle fuer den Datenaustausch im Gesundheitswesen", }, }, }, }, }, new DataSourceType { version = "1.1", DataContainer = new DataContainerType { type = ExtraContainerType.File, name = fileName, created = now, createdSpecified = true, encoding = ExtraContainerEncoding.Utf8, } }, }, }; } ValidateRequest(message, OstcMessageType.Application); var messageData = OstcExtraSerializer.Iso88591.Serialize(message); var request = CreateRequest(Network.Requests.Application); using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null)) { requestStream.Write(messageData, 0, messageData.Length); } using (var response = await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)) { var serializer = new XmlSerializer(typeof(TransportResponseType)); var responseData = (TransportResponseType)serializer.Deserialize(response.GetResponseStream()); var flags = responseData.TransportHeader.GetFlags().ToList(); if (flags.Any(x => x.weight == ExtraFlagWeight.Error)) { throw new Ostc2Exception(flags); } return(new OstcApplicationResult { OrderId = responseData.TransportHeader.ResponseDetails.ResponseID.Value, Pkcs10 = p10Data.CertRequestDer, RSA = rsaPrivateKey, Hash = p10Data.PublicKeyHashRaw, }); } }
private void ValidateRequest(TransportRequestType request, OstcMessageType messageType) { var data = OstcUtils.Serialize(request, Encoding.UTF8); ValidateRequest(data, messageType); }