Jeden z producentów oprogramowania zwrócił nam uwagę,
że schema transakcji nakłada na atrybut
/Dokument/TrescDokumentu/Karta/DanePodmiotu[charakterPodmiotu]
ograniczenie wyrażenia regularnego [A-Z0-9]{4}.
Jednocześnie wartości w słowniku formularzy dla tego pola, miały
małą literę jako ostatni znak.
To powodowało, że walidator xsd odrzucał transakcje z kodami ze strony,
a walidator regułowy odrzucał transakcje z kodami zgodnymi z XSD.
Wprowadzone zmiany
Zmieniono w słowniku formularzy pisownię kodów charakteru podmiotu w transakcji na wielkie litery.
Po poprawce A01a stało się A01A, A01b stało się A01B itd.
Do pobrania jest zaktualizowany
walidator transakcji.
Kody transakcji w api oraz w karcie transakcji na stronie zostały poprawione.
curl -v --key ksm-kmk.rsa.pem --cert ksm-kmk.pem https://test.giif.mofnet.gov.pl/api/rest2018/instytucje/ * Trying 145.237.235.44... * TCP_NODELAY set * Connected to test.giif.mofnet.gov.pl (145.237.235.44) port 443 (#0) * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 1/3) * schannel: checking server certificate revocation * schannel: sending initial handshake data: sending 188 bytes... * schannel: sent initial handshake data: sent 188 bytes * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 2/3) * schannel: failed to receive handshake, need more data * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 2/3) * schannel: encrypted data got 3347 * schannel: encrypted data buffer: offset 3347 length 4096 * schannel: a client certificate has been requested * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 2/3) * schannel: encrypted data buffer: offset 3347 length 4371 * schannel: sending next handshake data: sending 100 bytes... * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 2/3) * schannel: encrypted data got 290 * schannel: encrypted data buffer: offset 290 length 4371 * schannel: SSL/TLS handshake complete * schannel: SSL/TLS connection with test.giif.mofnet.gov.pl port 443 (step 3/3) * schannel: stored credential handle in session cache > GET /api/rest2018/instytucje/ HTTP/1.1 > Host: test.giif.mofnet.gov.pl > User-Agent: curl/7.55.1 > Accept: */* > * schannel: client wants to read 102400 bytes * schannel: encdata_buffer resized 103424 * schannel: encrypted data buffer: offset 0 length 103424 * schannel: encrypted data got 250 * schannel: encrypted data buffer: offset 250 length 103424 * schannel: decrypted data length: 221 * schannel: decrypted data added: 221 * schannel: decrypted data cached: offset 221 length 102400 * schannel: encrypted data buffer: offset 0 length 103424 * schannel: decrypted data buffer: offset 221 length 102400 * schannel: schannel_recv cleanup * schannel: decrypted data returned 221 * schannel: decrypted data buffer: offset 0 length 102400 < HTTP/1.1 401 401 < Date: Fri, 05 Apr 2019 10:55:39 GMT < Server: Apache/2.4.38 (codeit) OpenSSL/1.1.1a < Content-Type: application/octet-stream < Content-Length: 57 < No authorization header provided. Can't validate the JWT.* Connection #0 to host test.giif.mofnet.gov.pl left intact
W poprzednim odcinku
W części pierwszej:
Utworzyliśmy instytucję obowiązaną o NIPie 0123456789.
Przesłaliśmy żądanie wystawienia certyfikatu komunikacyjnego wraz z CSRem.
W trakcie tworzenia CSRa, utworzyliśmy plik ksm-kmk.prv.pem z kluczem prywatnym.
Pobraliśmy certyfikat komunikacyjny i zapisaliśmy go w pliku ksm-kmk.pem.
Pobieranie listy dostępnych instytucji
Zacznijmy od pobrania listy instytucji obowiązanych, do których certyfikat komunikacyjny daje nam dostęp:
W najbliższych kilku postach postaram się zaprezentować flow.
Do prezentacji będę korzystał z głównie z narzędzi linii poleceń.
Początkowo zamierzałem wykorzystać polecenie cms z pakietu OpenSSL do podpisywania plików,
jednakże wersja stabilna nie tworzy dokumentów zgodnych z CAdES, a wersja rozwojowa, która
ma tryb zgodności z CAdES nie współpracuje jeszcze z engine_pkcs11 co uniemożliwia skorzystanie
z podpisu na karcie kryptograficznej.
Przygotowania
proCertum SmartSign
Niektóre żądania do API wymagają podpisania treści żądania podpisem kwalifikowanym.
W tym celu wykorzystam oprogramowanie proCertum SmartSign.
Składany podpis musi być w formacie CAdES/ETSI, podpis musi otaczć dokument, znakowanie czasem nie jest wymagane.
W proCertum SmartSign taką konfigurację uzyskałem wybierając opcje:
Signature format: CAdES/ETSI
Signature type: Internal signature
Digest function: SHA-256
Additional signature options:
Signature profile: “Do not include any additional information (BES)”.
cURL
Używam curl w domyślej wersji zainstalowanej w Ubuntu 18.04 LTS
curl --data-binary @rejestracja.xml.sig \ --header 'Content-Type: application/xml' \ https://test.giif.mofnet.gov.pl/api/rest2018/instytucje/ Przyjęto zgłoszenie Instytucji Obowiązanej bez CSRa.
W systemie produkcyjnym oznaczałoby to, że zgłoszenie instytucji zostało zarejestrowane
i oczekuje na zatwierdzenie przez pracownika Ministerstwa Finansów.
W systemie testowym rejestracja jest automatyczna.
openssl req -out ksm-kmk.csr -new -newkey rsa:2048 -nodes -keyout ksm-kmk.prv.pem Generating a 2048 bit RSA private key ................................................................+++ ............+++ unable to write 'random state' writing new private key to 'ksm-kmk.prv.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:. State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:. Organization Name (eg, company) [Internet Widgits Pty Ltd]:. Organizational Unit Name (eg, section) []:. Common Name (e.g. server FQDN or YOUR name) []:ksm-kmk Email Address []:.
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Poprawka do karty transakcji notarialnej na stronie
Zgłoszono brak możliwości wczytania karty transakcji notarialnej z pliku XML na stronie.
Poprawiłem kod deserializacji XMLa, w zakresie wczytywania podmiotów z karty transakcji,
to powinno umożliwić ponowne wczytanie wygenerowanego pliku XML.
Uwaga
Wczytywanie plików XML na stronie, pozwala wyłącznie na wczytanie pliku z jedną transakcją.
Projekt strony zakładał przesyłanie każdej transakcji wypełnionej na stronie w oddzielnym pliku.
Poprawka do walidatora transakcji
Błąd w walidatorze transakcji powodował, że dla niepoprawnego pliku mógł pojawić się
wyjątek NullPointerException.
ksm@ksm-7530:~/tmp$ java -jar ~/src/comp/xml2018/xml2018-cli/target/xml2018-cli-1.0.1.jar validate TrGiif.xml Apr 04, 2019 6:41:21 AM org.jboss.weld.bootstrap.WeldStartup <clinit> INFO: WELD-000900: 2.4.8 (Final) Apr 04, 2019 6:41:21 AM org.jboss.weld.environment.deployment.discovery.ReflectionDiscoveryStrategy processAnnotatedDiscovery INFO: WELD-ENV-000014: Falling back to Java Reflection for bean-discovery-mode="annotated" discovery. Add org.jboss:jandex to the classpath to speed-up startup. Apr 04, 2019 6:41:21 AM org.jboss.weld.bootstrap.WeldStartup startContainer INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. Apr 04, 2019 6:41:21 AM org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent INFO: WELD-ENV-002003: Weld SE container STATIC_INSTANCE initialized Exception in thread "main" picocli.CommandLine$ExecutionException: Error while calling command (pl.gov.mofnet.giif.xml2018.cli.RuleValidateCommand@30865a90): java.lang.NullPointerException at picocli.CommandLine.execute(CommandLine.java:1180) at picocli.CommandLine.access$800(CommandLine.java:141) at picocli.CommandLine$RunLast.handle(CommandLine.java:1367) at picocli.CommandLine$RunLast.handle(CommandLine.java:1335) at picocli.CommandLine$AbstractParseResultHandler.handleParseResult(CommandLine.java:1243) at picocli.CommandLine.parseWithHandlers(CommandLine.java:1526) at pl.gov.mofnet.giif.xml2018.cli.Main.init(Main.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88) at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:78) at org.jboss.weld.injection.MethodInvocationStrategy$SimpleMethodInvocationStrategy.invoke(MethodInvocationStrategy.java:129) at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:299) at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:277) at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:255) at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:269) at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:258) at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:154) at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:136) at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:716) at org.jboss.weld.environment.se.WeldContainer.fireContainerInitializedEvent(WeldContainer.java:233) at org.jboss.weld.environment.se.WeldContainer.endInitialization(WeldContainer.java:185) at org.jboss.weld.environment.se.Weld.initialize(Weld.java:789) at org.jboss.weld.environment.se.StartMain.go(StartMain.java:46) at org.jboss.weld.environment.se.StartMain.main(StartMain.java:55) Caused by: java.lang.NullPointerException at pl.gov.mofnet.giif.xml.tagstack.TagStack$TagEntry.<init>(TagStack.java:18) at pl.gov.mofnet.giif.xml.tagstack.TagStack.lambda$new$0(TagStack.java:52) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at pl.gov.mofnet.giif.xml.tagstack.TagStack.<init>(TagStack.java:52) at pl.gov.mofnet.giif.xml2018.validators.common.Violation.<init>(Violation.java:28) at pl.gov.mofnet.giif.xml2018.validators.common.Violation.<init>(Violation.java:34) at pl.gov.mofnet.giif.xml2018.validators.notariat.KartaNotariat2018Validator.sprawdzDanePodmiotu(KartaNotariat2018Validator.java:129) at pl.gov.mofnet.giif.xml2018.validators.notariat.KartaNotariat2018Validator.sprawdzPodmioty(KartaNotariat2018Validator.java:113) at pl.gov.mofnet.giif.xml2018.validators.notariat.KartaNotariat2018Validator.validateTransaction(KartaNotariat2018Validator.java:56) at pl.gov.mofnet.giif.xml2018.validators.notariat.KartaNotariat2018Validator.validateTransaction(KartaNotariat2018Validator.java:22) at pl.gov.mofnet.giif.xml2018.validators.common.StreamProcesor.readAndValidateKartaTr(StreamProcesor.java:91) at pl.gov.mofnet.giif.xml2018.validators.common.StreamProcesor.validateFileStructure(StreamProcesor.java:56) at pl.gov.mofnet.giif.xml2018.validators.common.Karta2018Validator.validateFile(Karta2018Validator.java:117) at pl.gov.mofnet.giif.xml2018.cli.RuleValidateCommand.validateFile(RuleValidateCommand.java:40) at pl.gov.mofnet.giif.xml2018.cli.AbstractValidateCommand.call(AbstractValidateCommand.java:41) at pl.gov.mofnet.giif.xml2018.cli.AbstractValidateCommand.call(AbstractValidateCommand.java:19) at picocli.CommandLine.execute(CommandLine.java:1173) ... 26 more
Linie 3-5 pobierają program i certyfikat do systemu testowego.
Kluczowa jest linia 5, która pobiera plik ustawień biblioteki Szafir SDK w wersji dla systemu Linux.
W końcowej części pliku szafir-sdk-settings.xml znajduje się sekcja CryptoProviders, a w niej wskazane
są położenia bibliotek PKCS#11 do obsługi kart kryptograficznych. Domyślnie skonfigurowana jest obsługa kart
wystawianych przez Certum, których używają programiści z MF. W tej sekcji można dodać kolejne tagi
HardwareProvider a w nich w tagu URI wskazać bibliotekę PKCS#11. Jeżeli biblioteka nie leży w ścieżce
przeszukiwania bibliotek (ldconfig -v 2>/dev/null | grep -v ^$'\t'), to należy podać pełną scieżkę do
niej jako URI, np: file:///opt/proCertumSmartSign/libSimplySignPKCS11.so.
Linia 6 pokazuje jak wywołać GUI.
Linia 7-10 jak użyć trybu linii poleceń.
Udostępniliśmy do pobrania off-line’owy walidator plików.
Jest to aplikacja uruchamiana z linii poleceń, do jej uruchomienia wymagana jest Java w wersji 1.8 lub wyższej.
Pod Windows można ją uruchomić jako:
1
giif-xml2018-cli.exe --help
Pod Linuksem i OS-X jako:
1
java -jar giif-xml2018-cli.exe --help
W rezultacie otrzymujemy wynik podobny do tego:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Apr 02, 2019 10:21:44 AM org.jboss.weld.bootstrap.WeldStartup <clinit> INFO: WELD-000900: 2.4.8 (Final) Apr 02, 2019 10:21:44 AM org.jboss.weld.environment.deployment.discovery.ReflectionDiscoveryStrategy processAnnotatedDiscovery INFO: WELD-ENV-000014: Falling back to Java Reflection for bean-discovery-mode="annotated" discovery. Add org.jboss:jandex to the classpath to speed-up startup. Apr 02, 2019 10:21:44 AM org.jboss.weld.bootstrap.WeldStartup startContainer INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. Apr 02, 2019 10:21:45 AM org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent INFO: WELD-ENV-002003: Weld SE container STATIC_INSTANCE initialized Usage: <main class> [-hV] [COMMAND] Prosta apka do walidacji plików. -h, --help Show this help message and exit. -V, --version Print version information and exit. Commands: validate Walidacja zgodności z regułami. xsd-validate Waliduj zgodność z XSD. Weld SE container STATIC_INSTANCE shut down by shutdown hook
Linie od 1 do 8 to log uruchamiania programu, jest on wypisywany na STDERR więc można go przekierować do /dev/null.
Logi są wypisywane przez java.utils.logging, więc można je skonfigurować jak w każdym innym programie javowym przez,
przez dodanie -Djava.util.logging.config.file=logging.properties przed -jar
Usage: <main class> xsd-validate [-hqV] [-f=<outputFormat>] [-o=<outputFile>] plik... Waliduj zgodność z XSD. plik... Pliki do walidacji. -f, --format=<outputFormat> Format wyniku walidacji: TEXT, JSON, CSV, domyślnie TEXT. -h, --help Show this help message and exit. -o, --output=<outputFile> Plik wynikowy, domyślnie STDOUT. -q, --quiet Nie wypisuj komunikatu błędu na STDOUT. -V, --version Print version information and exit. Weld SE container STATIC_INSTANCE shut down by shutdown hook
Jeżeli żaden plik nie zawierał błędu aplikacja zwróci status 0.
Jeżeli co najmniej jeden z przetwarzanych plików zawierał błędy aplikacja zwróci 1.
Przykład
1 2 3
$ java -jar xml2018-cli-1.0.1.jar xsd-validate ~/Downloads/wymiana_export_0000000000_Transakcja_testowa\(1\).xml 2> /dev/null Plik poprawny: /home/ksm/Downloads/wymiana_export_0000000000_Transakcja_testowa(1).xml Weld SE container STATIC_INSTANCE shut down by shutdown hook
Przykład z błędem
1 2 3
$ java -jar giif-xml2018-cli.exe xsd-validate -f CSV -o wymiana.csv ~/Downloads/wymiana_export_0000000000_Transakcja_testowa\(1\).xml 2> /dev/null Plik niepoprawny: /home/ksm/Downloads/wymiana_export_0000000000_Transakcja_testowa(1).xml Weld SE container STATIC_INSTANCE shut down by shutdown hook
Powyższe polecenie sprawdza plik i zapisuje napotkane błędy do pliku wymiana.csv w formacie CSV. Utworzony plik wymiana CSV
1 2
Plik,Typ,Położenie karty,Karta po tagu,Identyfikator karty,Poprzedni identyfikator,Położenie błędu,Błąd po tagu,Komunikat,Dotyczy tagów,Wartość,Wyjątek wymiana_export_0000000000_Transakcja_testowa(1).xml,BŁĄD,,/Dokument,Rekord Transakcja testowa,Przed pierwszym rekordem.,,,,,,"cvc-complex-type.2.4.a: Invalid content was found starting with element 't:DokumentTozsamosci'. One of '{""http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/10/10/giif/typy/"":PESEL, ""http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2018/10/10/giif/typy/"":DataUrodzenia}' is expected."
Usage: <main class> validate [-hqV] [-f=<outputFormat>] [-o=<outputFile>] plik... Walidacja zgodności z regułami. plik... Pliki do walidacji. -f, --format=<outputFormat> Format wyniku walidacji: TEXT, JSON, CSV, domyślnie TEXT. -h, --help Show this help message and exit. -o, --output=<outputFile> Plik wynikowy, domyślnie STDOUT. -q, --quiet Nie wypisuj komunikatu błędu na STDOUT. -V, --version Print version information and exit. Weld SE container STATIC_INSTANCE shut down by shutdown hook
Jeżeli żaden plik nie zawierał błędu aplikacja zwróci status 0.
Jeżeli co najmniej jeden z przetwarzanych plików zawierał błędy aplikacja zwróci 1.
System jest przeznaczony dla Instucji Obowiązanych
oraz firm przygotowujących oprogramowanie dla Instytucji Obowiązanych
do testowania przesyłania danych do systemu SI*GIIF.
Status systemu testowego
System testowy NIE jest przystosowany do przetwarzania danych osobowych.
Dane przesyłane do systemu powinny być fikcyjne lub zanonimizowane.
Przesłanie danych do systemu testowego NIE stanowi realizacji obowiązku raportowania,
nakładanego przez ustawę o przeciwdziałniu praniu pieniędzy oraz finansowaniu terroryzmu
z dnia 1 marca 2018r.
Zakres systemu testowego
Aktualnie system testowy udostępnia API do przesyłania danych
do systemu SI*GIIF.
Implementacja API w systemie testowym może różnić się w dwóch aspektach od systemu produkcyjnego:
Czynności sprawdzające, związanej z rejestracją instytucji i rejestracją użytkowników,
które w systemie produkcyjnym są wkonywane przez pracowników Ministerstwa Finansów,
są pomijane (rejestracja, która jest formalnie poprawna, zostaje automatycznie zatwierdzona).
Poprawki i nowe funkcjonalności trafiają do systemu testowego przed wdrożeniem
ich w systemie produkcyjnym (system testowy pokazuje jak będzie działał system produkcyjny
za kilka tygodni).
UPO
System testowy dla poprawnych plików danych wystawia dokumenty o strukturze takiej
jak UPO z systemu SI*GIIF, jednakże pliki te są podpisane
certyfikatem testowym
wystawionym przez testowe CA.
Korzystanie z systemu
Aby móc korzystać z systemu należy:
Posiadać podpis elektroniczny.
Dokonać rejestracji Instytucji Obowiązanej (lub developera), można to zrobić przez wypełnienie
formularza identyfikującego na stronie systemu testowego, lub przez API systemu.
Rejestracja umożliwia skorzystanie z API do wygenerowania certyfikatu komunikacyjnego.
Przekazywane pliki muszą być zaszyfrowane certyfikatem testowym, dostępnym na stronie systemu testowego.
Możliwe jest pobranie walidatora, który służy do sprawdzenia poprawności plików z transakcjami.
Opis użycia programu znajduje się w blogu.