コード例 #1
0
ファイル: OstcClient.cs プロジェクト: JuryOberst/Itsg.Ostc
        /// <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);
            }
        }
コード例 #2
0
ファイル: OstcClient.cs プロジェクト: JuryOberst/Itsg.Ostc
        /// <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);
                }
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: OstcClient.cs プロジェクト: JuryOberst/Itsg.Ostc
        /// <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);
            }
        }
コード例 #7
0
ファイル: OstcClient.cs プロジェクト: JuryOberst/Itsg.Ostc
        /// <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,
                });
            }
        }
コード例 #8
0
ファイル: OstcClient.cs プロジェクト: JuryOberst/Itsg.Ostc
        private void ValidateRequest(TransportRequestType request, OstcMessageType messageType)
        {
            var data = OstcUtils.Serialize(request, Encoding.UTF8);

            ValidateRequest(data, messageType);
        }