sepafm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +8 -0
- data/README.md +236 -0
- data/Rakefile +10 -0
- data/lib/danske_get_bank_certificate_test.rb +15 -0
- data/lib/sepa/application_request.rb +182 -0
- data/lib/sepa/application_response.rb +123 -0
- data/lib/sepa/client.rb +79 -0
- data/lib/sepa/danske_testing/keys/danske_encryption.crt +24 -0
- data/lib/sepa/filedescriptor.rb +7 -0
- data/lib/sepa/filetypeservice.rb +6 -0
- data/lib/sepa/nordea_testing/keys/CSR.csr +0 -0
- data/lib/sepa/nordea_testing/keys/nordea.crt +27 -0
- data/lib/sepa/nordea_testing/keys/nordea.key +19 -0
- data/lib/sepa/nordea_testing/response/content_053.xml +998 -0
- data/lib/sepa/nordea_testing/response/content_054.xml +1 -0
- data/lib/sepa/nordea_testing/response/download_file_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/download_filelist_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/get_user_info_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/upload_file_response.xml +14 -0
- data/lib/sepa/response.rb +177 -0
- data/lib/sepa/sender_verifier.rb +15 -0
- data/lib/sepa/signature.rb +7 -0
- data/lib/sepa/soap_builder.rb +395 -0
- data/lib/sepa/soap_danske.rb +47 -0
- data/lib/sepa/soap_nordea.rb +68 -0
- data/lib/sepa/userfiletype.rb +16 -0
- data/lib/sepa/version.rb +3 -0
- data/lib/sepa/wsdl/wsdl_danske.xml +234 -0
- data/lib/sepa/wsdl/wsdl_danske_cert.xml +280 -0
- data/lib/sepa/wsdl/wsdl_nordea.xml +234 -0
- data/lib/sepa/wsdl/wsdl_nordea_cert.xml +187 -0
- data/lib/sepa/xml_parser.rb +291 -0
- data/lib/sepa/xml_schemas/application_request.xsd +135 -0
- data/lib/sepa/xml_schemas/application_response.xsd +311 -0
- data/lib/sepa/xml_schemas/cert_application_request.xsd +107 -0
- data/lib/sepa/xml_schemas/danske_pki.xsd +334 -0
- data/lib/sepa/xml_schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd +195 -0
- data/lib/sepa/xml_schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd +108 -0
- data/lib/sepa/xml_schemas/soap.xsd +126 -0
- data/lib/sepa/xml_schemas/wsdl.xml +310 -0
- data/lib/sepa/xml_schemas/xml.xsd +287 -0
- data/lib/sepa/xml_schemas/xmldsig-core-schema.xsd +318 -0
- data/lib/sepa/xml_templates/application_request/create_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/danske_get_bank_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/download_file.xml +32 -0
- data/lib/sepa/xml_templates/application_request/download_file_list.xml +29 -0
- data/lib/sepa/xml_templates/application_request/get_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/get_user_info.xml +26 -0
- data/lib/sepa/xml_templates/application_request/upload_file.xml +29 -0
- data/lib/sepa/xml_templates/soap/create_certificate.xml +15 -0
- data/lib/sepa/xml_templates/soap/danske_get_bank_certificate.xml +14 -0
- data/lib/sepa/xml_templates/soap/download_file.xml +16 -0
- data/lib/sepa/xml_templates/soap/download_file_list.xml +16 -0
- data/lib/sepa/xml_templates/soap/get_certificate.xml +13 -0
- data/lib/sepa/xml_templates/soap/get_user_info.xml +16 -0
- data/lib/sepa/xml_templates/soap/header.xml +37 -0
- data/lib/sepa/xml_templates/soap/upload_file.xml +16 -0
- data/lib/sepa.rb +21 -0
- data/lib/sepa_client_testing_mika.rb +32 -0
- data/lib/sepa_client_testing_tiere.rb +80 -0
- data/sepa.gemspec +29 -0
- data/test/sepa/application_request_test.rb +423 -0
- data/test/sepa/application_response_test.rb +238 -0
- data/test/sepa/cert_application_request_test.rb +99 -0
- data/test/sepa/client_test.rb +425 -0
- data/test/sepa/danske_test_keys/danskeroot.pem +25 -0
- data/test/sepa/danske_test_keys/encryption_pkcs.csr +0 -0
- data/test/sepa/danske_test_keys/signing_key.pem +27 -0
- data/test/sepa/danske_test_keys/signing_pkcs.csr +0 -0
- data/test/sepa/nordea_cert_request_soap_builder_test.rb +112 -0
- data/test/sepa/nordea_generic_soap_builder_test.rb +427 -0
- data/test/sepa/nordea_test_keys/nordea.crt +27 -0
- data/test/sepa/nordea_test_keys/nordea.key +19 -0
- data/test/sepa/nordea_test_keys/root_cert.cer +0 -0
- data/test/sepa/nordea_test_keys/testcert.csr +0 -0
- data/test/sepa/response_test.rb +269 -0
- data/test/sepa/sepa_test.rb +20 -0
- data/test/sepa/test_files/invalid.wsdl +1 -0
- data/test/sepa/test_files/test_responses/df.xml +20 -0
- data/test/sepa/test_files/test_responses/dfl.xml +20 -0
- data/test/sepa/test_files/test_responses/gui.xml +20 -0
- data/test/sepa/test_files/test_responses/uf.xml +20 -0
- data/test/sepa/user_file_type_test.rb +21 -0
- data/test/sepa/xml_parser_test.rb +73 -0
- data/test/test_helper.rb +9 -0
- metadata +256 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
<c2b:ApplicationResponse xmlns:c2b="http://bxd.fi/xmldata/"><c2b:CustomerId>679155330</c2b:CustomerId><c2b:Timestamp>2010-09-10T10:20:38+02:00</c2b:Timestamp><c2b:ResponseCode>00</c2b:ResponseCode><c2b:ResponseText>OK.</c2b:ResponseText><c2b:Encrypted>false</c2b:Encrypted><c2b:Compressed>false</c2b:Compressed><c2b:UserFileTypes><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>HAELASKUT</c2b:FileType><c2b:FileTypeName>E-invoice to payer FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-FI3329501800008512</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-FI5229501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-FI7429501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-FI8319503000004327</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>HTMKTL</c2b:FileType><c2b:FileTypeName>Reference payments (html) FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>HTMKTO</c2b:FileType><c2b:FileTypeName>Account statement (html) FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000012445</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000086423</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>HYLLASKUT</c2b:FileType><c2b:FileTypeName>Rejected e-invoices to sender FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-00370011111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>INFO</c2b:FileType><c2b:FileTypeName>Info</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId/><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>N</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>KORKO</c2b:FileType><c2b:FileTypeName>Interest</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId/><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>N</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>KTL</c2b:FileType><c2b:FileTypeName>Reference Payments FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>LAHLASKUT</c2b:FileType><c2b:FileTypeName>E-invoice from invoicer FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Upload</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-00370011111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>LMP300</c2b:FileType><c2b:FileTypeName>Bill Payment service FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Upload</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-011111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>LMPPAL</c2b:FileType><c2b:FileTypeName>Bill payment service feedback FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-011111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>?</c2b:ServiceId><c2b:ServiceIdOwnerName>?</c2b:ServiceIdOwnerName><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText>?</c2b:ServiceIdText></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>NDCORPAYL</c2b:FileType><c2b:FileTypeName>Corporate payments - feedback FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-111111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>NDCORPAYS</c2b:FileType><c2b:FileTypeName>Corporate payments FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Upload</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-111111111</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>TITO</c2b:FileType><c2b:FileTypeName>Account Statement FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000012445</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000086423</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>TS</c2b:FileType><c2b:FileTypeName>Salaries and pensions FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Upload</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-123456789</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>TSPAL</c2b:FileType><c2b:FileTypeName>Salaries and pensions feedback FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-123456789</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>?</c2b:ServiceId><c2b:ServiceIdOwnerName>?</c2b:ServiceIdOwnerName><c2b:ServiceIdType>O</c2b:ServiceIdType><c2b:ServiceIdText>?</c2b:ServiceIdText></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>TXTKTL</c2b:FileType><c2b:FileTypeName>Reference payments (txt) FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>TXTKTO</c2b:FileType><c2b:FileTypeName>Account statement (txt) FI</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000010</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000000051</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000012445</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-19503000086423</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000014</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService><c2b:FileTypeService><c2b:ServiceId>NDEAFIHHXXX-FI1-EUR-29501800000022</c2b:ServiceId><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>A</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType><c2b:UserFileType><c2b:TargetId>11111111A1</c2b:TargetId><c2b:FileType>VKEUR</c2b:FileType><c2b:FileTypeName>Rates of exchange</c2b:FileTypeName><c2b:Country>FI</c2b:Country><c2b:Direction>Download</c2b:Direction><c2b:FileTypeServices><c2b:FileTypeService><c2b:ServiceId/><c2b:ServiceIdOwnerName/><c2b:ServiceIdType>N</c2b:ServiceIdType><c2b:ServiceIdText/></c2b:FileTypeService></c2b:FileTypeServices></c2b:UserFileType></c2b:UserFileTypes><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
2
|
+
<SignedInfo>
|
3
|
+
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
4
|
+
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
5
|
+
<Reference URI="">
|
6
|
+
<Transforms>
|
7
|
+
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
8
|
+
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
9
|
+
</Transforms>
|
10
|
+
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
11
|
+
<DigestValue>gNqDLvLt1Y3ma0hEFfZe3HR4hYg=</DigestValue>
|
12
|
+
</Reference>
|
13
|
+
</SignedInfo>
|
14
|
+
<SignatureValue>stMf9BuVXOD8XFxvJ3eTAxNfP0j/bm22YNJCpGLjN4TgRHBrS0OgY0WgG8O1TmptlGc63MyhwddGdIj9uYob7/q7uAhG1teY0bRCEvPc4uobDcZ2Umoqt66B2X4CuKIrdCeJNY/GBiSPIW3scA+y19F3rsnzIO3eUqZ7t8osyAk=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIID2TCCAsGgAwIBAgIEAKwkgTANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJTRTEeMBwGA1UEChMVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMSYwJAYDVQQDEx1Ob3JkZWEgQ29ycG9yYXRlIFNlcnZlciBDQSAwMTEUMBIGA1UEBRMLNTE2NDA2LTAxMjAwHhcNMDgxMDE3MTIzMDQxWhcNMTAxMDE3MTIzMDQxWjBmMQswCQYDVQQGEwJTRTEeMBwGA1UECgwVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMRIwEAYDVQQLDAlOb3JkZWEgSVQxIzAhBgNVBAMMGkZpbGUgVHJhbnNmZXIgV2ViIFNlcnZpY2VzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI78vhz4V6P2jWj4LPIbBv2GDg6DWPhMT0fD90mu+/N+P2wn5RcIyEVpxWWRyP+oDqq5bW+J0Ni0GF9qRB8aTSBXaZ3AHH+tWWwxXk10RhZ47fNH+yzF7HDHmVJ++OkOpELlmUDb5tX+m+qtdL8nkIywvTYBMOrp3lGgWw1NiBMwIDAQABo4IBDDCCAQgwCQYDVR0TBAIwADARBgNVHQ4ECgQISLk+63zpZ78wEwYDVR0jBAwwCoAIRMeT2dl7VsEwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5ub3JkZWEuc2UvU0NBMDEwDgYDVR0PAQH/BAQDAgWgMIGJBgNVHR8EgYEwfzB9oHugeYZ3bGRhcDovL2xkYXAubmIuc2UvY249Tm9yZGVhJTIwQ29ycG9yYXRlJTIwU2VydmVyJTIwQ0ElMjAwMSxvPU5vcmRlYSUyMEJhbmslMjBBQiUyMChwdWJsKSxjPVNFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwDQYJKoZIhvcNAQEFBQADggEBAKqnBbdpbOhhJQLasFA8wUzHciMK6ACGIIPbaxU1X/aKVIpZ+rS92OB0TcIqmcBoAXLyFmzOjNPZCxntp/xC2J1y3Sd0Nbh/6LpwNLkbleinakaR4WnRdV3u38yzC2eczAIIZj/rnxylwh++JmfOdK8/T5ynKYJYx5UoMcG8WICmBRfEWId5/5hrr7PiN5neryz0zRUnmG4r9ML0X93C59yTmjcZXoVZwxIkwfzDTZxlPT1m/sAjOCnSHHuCMmJSXXWOeYJLIOdASgVOl7x6xdKKw6uOD0F2IC1xjpB3XBYMR2jxcb6SSyAkXgBNCPUGFUUkcUOk3+KwIu2Cjp7u1Ro=</X509Certificate><X509IssuerSerial><X509IssuerName>serialNumber=516406-0120, CN=Nordea Corporate Server CA 01, O=Nordea Bank AB (publ), C=SE</X509IssuerName><X509SerialNumber>11281537</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></c2b:ApplicationResponse>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<c2b:ApplicationResponse xmlns:c2b="http://bxd.fi/xmldata/"><c2b:CustomerId>679155330</c2b:CustomerId><c2b:Timestamp>2010-09-13T13:06:34.16+03:00</c2b:Timestamp><c2b:ResponseCode>00</c2b:ResponseCode><c2b:ResponseText>OK.</c2b:ResponseText><c2b:Encrypted>false</c2b:Encrypted><c2b:Compressed>false</c2b:Compressed><c2b:AmountTotal>2312.00</c2b:AmountTotal><c2b:TransactionCount>3</c2b:TransactionCount><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
2
|
+
<SignedInfo>
|
3
|
+
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
4
|
+
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
5
|
+
<Reference URI="">
|
6
|
+
<Transforms>
|
7
|
+
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
8
|
+
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
9
|
+
</Transforms>
|
10
|
+
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
11
|
+
<DigestValue>zXN3gtukcU0Hrn5fEJvhkLKMVIs=</DigestValue>
|
12
|
+
</Reference>
|
13
|
+
</SignedInfo>
|
14
|
+
<SignatureValue>ud/gAtrrxg+B28CMV/BPaRSSRqmqNdWjsnoEm3yT9avvq8MV39reVXi/RULw+lSJUQYXDFgfkRxRVUKK71T4PlrdlMK8gfqvREVvPdLXqmtdEvuGXa+YGfeRMgO+IE7mnvb9hTsZi2TBSle/w9BHjrfv1mrg0cFwCovcro5JUXw=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIID2TCCAsGgAwIBAgIEAKwkgTANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJTRTEeMBwGA1UEChMVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMSYwJAYDVQQDEx1Ob3JkZWEgQ29ycG9yYXRlIFNlcnZlciBDQSAwMTEUMBIGA1UEBRMLNTE2NDA2LTAxMjAwHhcNMDgxMDE3MTIzMDQxWhcNMTAxMDE3MTIzMDQxWjBmMQswCQYDVQQGEwJTRTEeMBwGA1UECgwVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMRIwEAYDVQQLDAlOb3JkZWEgSVQxIzAhBgNVBAMMGkZpbGUgVHJhbnNmZXIgV2ViIFNlcnZpY2VzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI78vhz4V6P2jWj4LPIbBv2GDg6DWPhMT0fD90mu+/N+P2wn5RcIyEVpxWWRyP+oDqq5bW+J0Ni0GF9qRB8aTSBXaZ3AHH+tWWwxXk10RhZ47fNH+yzF7HDHmVJ++OkOpELlmUDb5tX+m+qtdL8nkIywvTYBMOrp3lGgWw1NiBMwIDAQABo4IBDDCCAQgwCQYDVR0TBAIwADARBgNVHQ4ECgQISLk+63zpZ78wEwYDVR0jBAwwCoAIRMeT2dl7VsEwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcC5ub3JkZWEuc2UvU0NBMDEwDgYDVR0PAQH/BAQDAgWgMIGJBgNVHR8EgYEwfzB9oHugeYZ3bGRhcDovL2xkYXAubmIuc2UvY249Tm9yZGVhJTIwQ29ycG9yYXRlJTIwU2VydmVyJTIwQ0ElMjAwMSxvPU5vcmRlYSUyMEJhbmslMjBBQiUyMChwdWJsKSxjPVNFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwDQYJKoZIhvcNAQEFBQADggEBAKqnBbdpbOhhJQLasFA8wUzHciMK6ACGIIPbaxU1X/aKVIpZ+rS92OB0TcIqmcBoAXLyFmzOjNPZCxntp/xC2J1y3Sd0Nbh/6LpwNLkbleinakaR4WnRdV3u38yzC2eczAIIZj/rnxylwh++JmfOdK8/T5ynKYJYx5UoMcG8WICmBRfEWId5/5hrr7PiN5neryz0zRUnmG4r9ML0X93C59yTmjcZXoVZwxIkwfzDTZxlPT1m/sAjOCnSHHuCMmJSXXWOeYJLIOdASgVOl7x6xdKKw6uOD0F2IC1xjpB3XBYMR2jxcb6SSyAkXgBNCPUGFUUkcUOk3+KwIu2Cjp7u1Ro=</X509Certificate><X509IssuerSerial><X509IssuerName>serialNumber=516406-0120, CN=Nordea Corporate Server CA 01, O=Nordea Bank AB (publ), C=SE</X509IssuerName><X509SerialNumber>11281537</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></c2b:ApplicationResponse>
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module Sepa
|
2
|
+
class Response
|
3
|
+
def initialize(response)
|
4
|
+
@response = response
|
5
|
+
|
6
|
+
if !@response.respond_to?(:canonicalize)
|
7
|
+
fail ArgumentError,
|
8
|
+
"The response you provided is not a valid Nokogiri::XML file."
|
9
|
+
elsif !valid_against_schema?(@response)
|
10
|
+
fail ArgumentError,
|
11
|
+
"The response you provided doesn't validate against soap schema."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the x509 certificate embedded in the soap as an
|
16
|
+
# OpenSSL::X509::Certificate
|
17
|
+
def certificate
|
18
|
+
cert_value = @response.at_css(
|
19
|
+
'wsse|BinarySecurityToken',
|
20
|
+
'wsse' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ws' \
|
21
|
+
'security-secext-1.0.xsd'
|
22
|
+
).content.gsub(/\s+/, "")
|
23
|
+
|
24
|
+
cert = process_cert_value(cert_value)
|
25
|
+
|
26
|
+
begin
|
27
|
+
cert = OpenSSL::X509::Certificate.new(cert)
|
28
|
+
rescue => e
|
29
|
+
fail OpenSSL::X509::CertificateError,
|
30
|
+
"The certificate embedded to the soap response could not be process" \
|
31
|
+
"ed. It's most likely corrupted. OpenSSL had this to say: #{e}."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Verifies that the soap's certificate is trusted.
|
36
|
+
def cert_is_trusted?(root_cert)
|
37
|
+
if root_cert.subject == certificate.issuer
|
38
|
+
certificate.verify(root_cert.public_key)
|
39
|
+
else
|
40
|
+
fail SecurityError,
|
41
|
+
"The issuer of the certificate doesn't match the subject of the roo" \
|
42
|
+
"t certificate."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Verifies that all digest values in the response match the actual ones.
|
47
|
+
# Takes an optional verbose parameter to show which digests didn't match
|
48
|
+
# i.e. verbose: true
|
49
|
+
def hashes_match?(options = {})
|
50
|
+
digests = find_digest_values(@response)
|
51
|
+
nodes = find_nodes_to_verify(@response, digests)
|
52
|
+
|
53
|
+
verified_digests = digests.select do |uri, digest|
|
54
|
+
uri = uri.sub(/^#/, '')
|
55
|
+
digest == nodes[uri]
|
56
|
+
end
|
57
|
+
|
58
|
+
if digests == verified_digests
|
59
|
+
true
|
60
|
+
else
|
61
|
+
unverified_digests = digests.select do |uri, digest|
|
62
|
+
uri = uri.sub(/^#/, '')
|
63
|
+
digest != nodes[uri]
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:verbose]
|
67
|
+
puts "These digests failed to verify: #{unverified_digests}."
|
68
|
+
end
|
69
|
+
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Verifies the signature by extracting the public key from the certificate
|
75
|
+
# embedded in the soap header and verifying the signature value with that.
|
76
|
+
def signature_is_valid?
|
77
|
+
node = @response.at_css('xmlns|SignedInfo',
|
78
|
+
'xmlns' => 'http://www.w3.org/2000/09/xmldsig#')
|
79
|
+
|
80
|
+
node = node.canonicalize(
|
81
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
|
82
|
+
inclusive_namespaces=nil,with_comments=false
|
83
|
+
)
|
84
|
+
|
85
|
+
signature = @response.at_css(
|
86
|
+
'xmlns|SignatureValue',
|
87
|
+
'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
|
88
|
+
).content
|
89
|
+
|
90
|
+
signature = Base64.decode64(signature)
|
91
|
+
|
92
|
+
certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, node)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Gets the application response from the response as an Nokogiri::XML
|
96
|
+
# document
|
97
|
+
def application_response
|
98
|
+
ar = @response.at_css('mod|ApplicationResponse').content
|
99
|
+
ar = Base64.decode64(ar)
|
100
|
+
Nokogiri::XML(ar)
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# Finds all reference nodes with digest values in the document and returns
|
106
|
+
# a hash with uri as the key and digest as the value.
|
107
|
+
def find_digest_values(doc)
|
108
|
+
references = {}
|
109
|
+
reference_nodes = @response.css(
|
110
|
+
'xmlns|Reference',
|
111
|
+
'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
|
112
|
+
)
|
113
|
+
|
114
|
+
reference_nodes.each do |node|
|
115
|
+
uri = node.attr('URI')
|
116
|
+
digest_value = node.at_css(
|
117
|
+
'xmlns|DigestValue',
|
118
|
+
'xmlns' => 'http://www.w3.org/2000/09/xmldsig#'
|
119
|
+
).content
|
120
|
+
|
121
|
+
references[uri] = digest_value
|
122
|
+
end
|
123
|
+
|
124
|
+
references
|
125
|
+
end
|
126
|
+
|
127
|
+
# Finds nodes to verify by comparing their id's to the uris' in the
|
128
|
+
# references hash.
|
129
|
+
def find_nodes_to_verify(doc, references)
|
130
|
+
nodes = {}
|
131
|
+
references.each do |uri, digest_value|
|
132
|
+
uri = uri.sub(/^#/, '')
|
133
|
+
node = doc.at_css(
|
134
|
+
"[wsu|Id='" + uri + "']",
|
135
|
+
'wsu' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss' \
|
136
|
+
'-wssecurity-utility-1.0.xsd'
|
137
|
+
)
|
138
|
+
|
139
|
+
nodes[uri] = calculate_digest(node)
|
140
|
+
end
|
141
|
+
|
142
|
+
nodes
|
143
|
+
end
|
144
|
+
|
145
|
+
def calculate_digest(node)
|
146
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
147
|
+
|
148
|
+
canon_node = node.canonicalize(
|
149
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
|
150
|
+
inclusive_namespaces=nil,with_comments=false
|
151
|
+
)
|
152
|
+
|
153
|
+
Base64.encode64(sha1.digest(canon_node)).gsub(/\s+/, "")
|
154
|
+
end
|
155
|
+
|
156
|
+
# Checks that the response is valid against soap schema.
|
157
|
+
def valid_against_schema?(doc)
|
158
|
+
schemas_path = File.expand_path('../../../lib/sepa/xml_schemas',
|
159
|
+
__FILE__)
|
160
|
+
|
161
|
+
Dir.chdir(schemas_path) do
|
162
|
+
xsd = Nokogiri::XML::Schema(IO.read('soap.xsd'))
|
163
|
+
xsd.valid?(doc)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Takes the certificate from the response, adds begin and end
|
168
|
+
# certificate texts and splits it into multiple lines so that OpenSSL
|
169
|
+
# can read it.
|
170
|
+
def process_cert_value(cert_value)
|
171
|
+
cert = "-----BEGIN CERTIFICATE-----\n"
|
172
|
+
cert += cert_value.to_s.gsub(/\s+/, "").scan(/.{1,64}/).join("\n")
|
173
|
+
cert += "\n"
|
174
|
+
cert += "-----END CERTIFICATE-----"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sepa
|
2
|
+
class SenderVerifier
|
3
|
+
def initialize(soap_response)
|
4
|
+
@soap_response = Nokogiri::XML(soap_response)
|
5
|
+
end
|
6
|
+
|
7
|
+
def get_digest_values
|
8
|
+
@soap_response.remove_namespaces!
|
9
|
+
digest_nodes = @soap_response.xpath("//Reference/dsig:DigestValue")
|
10
|
+
end
|
11
|
+
|
12
|
+
def calculate_digest
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,395 @@
|
|
1
|
+
module Sepa
|
2
|
+
class SoapBuilder
|
3
|
+
# SoapBuilder checks and validates incoming params and creates the SOAP structure
|
4
|
+
def initialize(params)
|
5
|
+
|
6
|
+
check_params(params)
|
7
|
+
# Generate a request ID for the request
|
8
|
+
params[:request_id] = generate_request_id
|
9
|
+
|
10
|
+
# Check if the bank&command need keys/certificates/csr's
|
11
|
+
@params = initialize_certificates_and_csr(params)
|
12
|
+
|
13
|
+
check_if_bank_allows_command(@params)
|
14
|
+
|
15
|
+
@ar = ApplicationRequest.new(@params).get_as_base64
|
16
|
+
|
17
|
+
@bank = @params.fetch(:bank)
|
18
|
+
find_correct_bank_extension(@bank)
|
19
|
+
|
20
|
+
@template_path = File.expand_path('../xml_templates/soap/', __FILE__)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_xml
|
24
|
+
# Returns a complete SOAP message in xml format
|
25
|
+
find_correct_build(@params).to_xml
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_ar_as_base64
|
29
|
+
@ar
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def generate_request_id
|
35
|
+
reqid = SecureRandom.random_number(1000).to_s<<SecureRandom.random_number(1000).to_s
|
36
|
+
reqid
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_correct_bank_extension(bank)
|
40
|
+
case bank
|
41
|
+
when :danske
|
42
|
+
self.extend(DanskeSoapRequest)
|
43
|
+
when :nordea
|
44
|
+
self.extend(NordeaSoapRequest)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Generic building steps
|
49
|
+
def calculate_digest(doc, node)
|
50
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
51
|
+
|
52
|
+
node = doc.at_css(node)
|
53
|
+
|
54
|
+
canon_node = node.canonicalize(
|
55
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,
|
56
|
+
inclusive_namespaces=nil,with_comments=false
|
57
|
+
)
|
58
|
+
|
59
|
+
Base64.encode64(sha1.digest(canon_node)).gsub(/\s+/, "")
|
60
|
+
end
|
61
|
+
|
62
|
+
def calculate_signature(doc, node, private_key)
|
63
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
64
|
+
|
65
|
+
node = doc.at_css(node)
|
66
|
+
|
67
|
+
canon_signed_info_node = node.canonicalize(
|
68
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,inclusive_namespaces=nil,
|
69
|
+
with_comments=false
|
70
|
+
)
|
71
|
+
|
72
|
+
signature = private_key.sign(sha1, canon_signed_info_node)
|
73
|
+
|
74
|
+
Base64.encode64(signature).gsub(/\s+/, "")
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_body_template(command)
|
78
|
+
case command
|
79
|
+
when :download_file_list
|
80
|
+
path = "#{@template_path}/download_file_list.xml"
|
81
|
+
when :get_user_info
|
82
|
+
path = "#{@template_path}/get_user_info.xml"
|
83
|
+
when :upload_file
|
84
|
+
path = "#{@template_path}/upload_file.xml"
|
85
|
+
when :download_file
|
86
|
+
path = "#{@template_path}/download_file.xml"
|
87
|
+
when :get_certificate
|
88
|
+
path = "#{@template_path}/get_certificate.xml"
|
89
|
+
when :get_bank_certificate
|
90
|
+
path = "#{@template_path}/danske_get_bank_certificate.xml"
|
91
|
+
end
|
92
|
+
|
93
|
+
body_template = File.open(path)
|
94
|
+
body = Nokogiri::XML(body_template)
|
95
|
+
body_template.close
|
96
|
+
|
97
|
+
body
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_node(doc, node, value)
|
101
|
+
doc.at_css(node).content = value
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_body_to_header(header, body)
|
105
|
+
body = body.at_css('env|Body')
|
106
|
+
header.root.add_child(body)
|
107
|
+
header
|
108
|
+
end
|
109
|
+
|
110
|
+
def extract_public_key(cert)
|
111
|
+
pkey = cert.public_key
|
112
|
+
pkey = OpenSSL::PKey::RSA.new(pkey)
|
113
|
+
|
114
|
+
pkey
|
115
|
+
end
|
116
|
+
|
117
|
+
def format_cert(cert)
|
118
|
+
cert = cert.to_s
|
119
|
+
cert = cert.split('-----BEGIN CERTIFICATE-----')[1]
|
120
|
+
cert = cert.split('-----END CERTIFICATE-----')[0]
|
121
|
+
cert.gsub!(/\s+/, "")
|
122
|
+
end
|
123
|
+
|
124
|
+
def load_header_template(template_path)
|
125
|
+
header_template = File.open("#{template_path}/header.xml")
|
126
|
+
header = Nokogiri::XML(header_template)
|
127
|
+
header_template.close
|
128
|
+
header
|
129
|
+
end
|
130
|
+
|
131
|
+
def process_header(header, body, private_key, cert)
|
132
|
+
set_node(header, 'wsu|Created', Time.now.iso8601)
|
133
|
+
|
134
|
+
set_node(header, 'wsu|Expires', (Time.now + 3600).iso8601)
|
135
|
+
|
136
|
+
timestamp_digest = calculate_digest(header,'wsu|Timestamp')
|
137
|
+
set_node(header,'dsig|Reference[URI="#dsfg8sdg87dsf678g6dsg6ds7fg"]' \
|
138
|
+
' dsig|DigestValue', timestamp_digest)
|
139
|
+
|
140
|
+
body_digest = calculate_digest(body, 'env|Body')
|
141
|
+
set_node(header,'dsig|Reference[URI="#sdf6sa7d86f87s6df786sd87f6s8fsd'\
|
142
|
+
'a"] dsig|DigestValue', body_digest)
|
143
|
+
|
144
|
+
signature = calculate_signature(header, 'dsig|SignedInfo', private_key)
|
145
|
+
set_node(header, 'dsig|SignatureValue', signature)
|
146
|
+
|
147
|
+
formatted_cert = format_cert(cert)
|
148
|
+
set_node(header, 'wsse|BinarySecurityToken', formatted_cert)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Tries to validate the parameters or their presence.
|
152
|
+
def check_params(params)
|
153
|
+
# Universally for all
|
154
|
+
check_params_hash(params)
|
155
|
+
check_certificate_and_key_requirements(params)
|
156
|
+
check_bank(params[:bank])
|
157
|
+
check_env(params[:environment])
|
158
|
+
check_customer_id(params[:customer_id])
|
159
|
+
|
160
|
+
# Generic commands
|
161
|
+
generic_commands = [:download_file,:download_file_list,:get_user_info]
|
162
|
+
|
163
|
+
# Depending on command
|
164
|
+
case params[:command]
|
165
|
+
when :get_certificate
|
166
|
+
check_pin(params[:pin])
|
167
|
+
check_service(params[:service])
|
168
|
+
when *generic_commands
|
169
|
+
if params[:bank] == :nordea
|
170
|
+
check_lang(params[:language])
|
171
|
+
check_status(params[:status])
|
172
|
+
check_target_id(params[:target_id])
|
173
|
+
check_file_type(params[:file_type])
|
174
|
+
end
|
175
|
+
when :upload_file
|
176
|
+
check_lang(params[:language])
|
177
|
+
check_target_id(params[:target_id])
|
178
|
+
check_file_type(params[:file_type])
|
179
|
+
check_content(params[:content])
|
180
|
+
when :get_bank_certificate
|
181
|
+
if params[:bank] == :danske
|
182
|
+
# Nothing here
|
183
|
+
end
|
184
|
+
else
|
185
|
+
fail ArgumentError, "Command not supported."
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def check_csr(csr)
|
190
|
+
unless csr
|
191
|
+
fail ArgumentError, "You didn't provide a certificate signing request"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def check_params_hash(params)
|
196
|
+
unless params.respond_to?(:each_pair)
|
197
|
+
fail ArgumentError, "You didn't provide a proper hash"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def check_bank(bank)
|
202
|
+
unless [:nordea, :danske].include?(bank)
|
203
|
+
fail ArgumentError, "You didn't provide a proper bank. " \
|
204
|
+
"Acceptable values are nordea OR danske."
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def check_request_id(request_id)
|
209
|
+
if request_id.to_i == 0
|
210
|
+
fail ArgumentError, "Request ID must be a number and not 0"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def check_keygen_type(keygen)
|
215
|
+
unless keygen
|
216
|
+
fail ArgumentError, "You didn't provide any Key Generator Type"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def check_encryption_pkcs10(enc_cert)
|
221
|
+
unless enc_cert
|
222
|
+
fail ArgumentError, "You didn't provide Encrypting certificate PKCS10"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def check_signing_pkcs10(sig_cert)
|
227
|
+
unless sig_cert
|
228
|
+
fail ArgumentError, "You didn't provide Signing certificate PKCS10"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def check_pin(pin)
|
233
|
+
unless pin
|
234
|
+
fail ArgumentError, "You didn't provide a secret PIN"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def check_private_key(private_key)
|
239
|
+
unless private_key.respond_to?(:sign)
|
240
|
+
fail ArgumentError, "You didn't provide a proper private key. The " \
|
241
|
+
"key has to be in OpenSSL::PKey::RSA - format."
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def check_cert(cert)
|
246
|
+
unless cert.respond_to?(:check_private_key)
|
247
|
+
fail ArgumentError, "You didn't provide a proper certificate. The " \
|
248
|
+
"certificate has to be in OpenSSL::X509::Certificate - format."
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def check_customer_id(customer_id)
|
253
|
+
unless customer_id && customer_id.respond_to?(:to_s) &&
|
254
|
+
customer_id.length <= 16
|
255
|
+
fail ArgumentError, "You didn't provide a proper customer id"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def check_env(env)
|
260
|
+
unless ['PRODUCTION', 'TEST', 'customertest'].include?(env)
|
261
|
+
fail ArgumentError, "You didn't provide a proper environment. " \
|
262
|
+
"Acceptable values are PRODUCTION or TEST or customertest."
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def check_status(status)
|
267
|
+
unless ['NEW', 'DOWNLOADED', 'ALL'].include?(status)
|
268
|
+
fail ArgumentError, "You didn't provide a proper status. " \
|
269
|
+
"Acceptable values are NEW, DOWNLOADED or ALL."
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def check_target_id(target_id)
|
274
|
+
unless target_id && target_id.respond_to?(:to_s) &&
|
275
|
+
target_id.length <= 80
|
276
|
+
fail ArgumentError, "You didn't provide a proper target id"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def check_lang(lang)
|
281
|
+
unless ['FI', 'SE', 'EN'].include?(lang)
|
282
|
+
fail ArgumentError, "You didn't provide a proper language. " \
|
283
|
+
"Acceptable values are FI, SE or EN."
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def check_file_type(file_type)
|
288
|
+
unless file_type && file_type.respond_to?(:to_s) &&
|
289
|
+
file_type.length <= 20
|
290
|
+
fail ArgumentError, "You didn't provide a proper file type. Check " \
|
291
|
+
"Your bank's documentation for available file types."
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def check_content(content)
|
296
|
+
unless content
|
297
|
+
fail ArgumentError, "You didn't provide any content."
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def check_service(service)
|
302
|
+
unless ['service', 'ISSUER', 'MATU'].include?(service)
|
303
|
+
fail ArgumentError, "You didn't provide a proper service."
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def check_hmac(hmac)
|
308
|
+
unless hmac
|
309
|
+
fail ArgumentError, "You didn't provide any HMAC."
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def check_if_bank_allows_command(params)
|
314
|
+
bank = params.fetch(:bank)
|
315
|
+
command = params.fetch(:command)
|
316
|
+
case bank
|
317
|
+
when :nordea
|
318
|
+
allowed_commands = [:get_certificate,:get_user_info,
|
319
|
+
:download_file_list,:download_file,:upload_file]
|
320
|
+
unless allowed_commands.include?(command)
|
321
|
+
fail ArgumentError, "You didn't provide a matching bank and service."
|
322
|
+
end
|
323
|
+
when :danske
|
324
|
+
allowed_commands = [:get_bank_certificate]
|
325
|
+
unless allowed_commands.include?(command)
|
326
|
+
fail ArgumentError, "You didn't provide a matching bank and service."
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def check_certificate_and_key_requirements(params)
|
332
|
+
command = params[:command]
|
333
|
+
require_private_and_cert = [:get_user_info,:download_file_list,
|
334
|
+
:download_file,:upload_file]
|
335
|
+
require_nothing = [:get_bank_certificate]
|
336
|
+
require_pkcs = [:get_certificate]
|
337
|
+
|
338
|
+
case command
|
339
|
+
when *require_private_and_cert
|
340
|
+
if params[:cert_path] == nil && params[:cert_plain] == nil
|
341
|
+
fail ArgumentError, "You must provide a path to the certificate " \
|
342
|
+
"or certificate in plain text"
|
343
|
+
end
|
344
|
+
if params[:private_key_path] == nil && params[:private_key_plain] == nil
|
345
|
+
fail ArgumentError, "You must provide a path to your private key " \
|
346
|
+
"or private key in plain text"
|
347
|
+
end
|
348
|
+
when *require_nothing
|
349
|
+
when *require_pkcs
|
350
|
+
if params[:csr_path] == nil && params[:csr_plain] == nil
|
351
|
+
fail ArgumentError, "You must provide a path to the CSR or CSR in plain text"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def initialize_certificates_and_csr(params)
|
357
|
+
begin
|
358
|
+
command = params[:command]
|
359
|
+
require_private_and_cert = [:get_user_info,:download_file_list,
|
360
|
+
:download_file,:upload_file]
|
361
|
+
require_nothing = [:get_bank_certificate]
|
362
|
+
require_pkcs = [:get_certificate]
|
363
|
+
|
364
|
+
case command
|
365
|
+
when *require_private_and_cert
|
366
|
+
if params[:cert_path] != nil
|
367
|
+
params[:cert] = OpenSSL::X509::Certificate.new(File.read(params.fetch(:cert_path)))
|
368
|
+
elsif params[:cert_plain] != nil
|
369
|
+
params[:cert] = OpenSSL::X509::Certificate.new(params.fetch(:cert_plain))
|
370
|
+
end
|
371
|
+
if params[:private_key_path] != nil
|
372
|
+
params[:private_key] = OpenSSL::PKey::RSA.new(File.read(params.fetch(:private_key_path)))
|
373
|
+
elsif params[:private_key_plain] != nil
|
374
|
+
params[:private_key] = OpenSSL::PKey::RSA.new(params.fetch(:private_key_plain))
|
375
|
+
end
|
376
|
+
check_private_key(params[:private_key])
|
377
|
+
check_cert(params[:cert])
|
378
|
+
when *require_nothing
|
379
|
+
when *require_pkcs
|
380
|
+
if params[:csr_path] != nil
|
381
|
+
params[:csr] = OpenSSL::X509::Request.new(File.read(params.fetch(:csr_path)))
|
382
|
+
elsif params[:csr_plain] != nil
|
383
|
+
params[:csr] = OpenSSL::X509::Request.new(params.fetch(:csr_plain))
|
384
|
+
end
|
385
|
+
check_csr(params[:csr])
|
386
|
+
else
|
387
|
+
fail ArgumentError, "No matching cases for initialize_certificates_and_csr"
|
388
|
+
end
|
389
|
+
params
|
390
|
+
rescue Exception => e
|
391
|
+
fail ArgumentError, "Parameter failed to initialize, check private key and cert path/plain"
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|