nemid 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,105 @@
1
+ module NemID
2
+ module Errors
3
+ class CAPPError < ResponseError
4
+ def initialize(msg='')
5
+ super(msg)
6
+ end
7
+ end
8
+
9
+ class CAPP001Error < CAPPError
10
+ def initialize
11
+ @da = "Nøgleappen kunne ikke blive indskrevet på grund af krænkelse af app'ens begrænsede identites type."
12
+ @en = "The code app could not be enrolled due to violation of the app's restricted identity type."
13
+ super
14
+ end
15
+ end
16
+
17
+ class CAPP002Error < CAPPError
18
+ def initialize
19
+ @da = "Din nøgleapp kunne ikke blive indskrevet på grund af krænkelse af suspensionsreglerne."
20
+ @en = "Your code app could not be enrolled due to violation of the suspension rules."
21
+ super
22
+ end
23
+ end
24
+
25
+ class CAPP003Error < CAPPError
26
+ def initialize
27
+ @da = "Din nøgleapp kunne ikke blive indskrevet på grund af, at dens app id ikke er i en aktiv status."
28
+ @en = "Your code app could not be enrolled due to its app id is not in status active."
29
+ super
30
+ end
31
+ end
32
+
33
+ class CAPP004Error < CAPPError
34
+ def initialize
35
+ @da = "Din nøgleapp er suspenderet eller spærret. Prøv at opdatere din nøgleapp."
36
+ @en = "Your code app is suspended or revoked. Please try and update your code app."
37
+ super
38
+ end
39
+ end
40
+
41
+ class CAPP006Error < CAPPError
42
+ def initialize
43
+ @da = "Din nøgleapp kunne ikke blive aktiveret, da den ikke kunne blive fundet for brugeren der loggede ind."
44
+ @en = "Your code app could not be activated as it could not be found for the user who logged in."
45
+ super
46
+ end
47
+ end
48
+
49
+ class CAPP007Error < CAPPError
50
+ def initialize
51
+ @da = "Din nøgleapp kunne ikke blive aktiveret, da den ikke har den korrekte status (VALIDATIONS_MISSING)."
52
+ @en = "Your code app could not be activated as it did not have the correct status (VALIDATION_MISSING)."
53
+ super
54
+ end
55
+ end
56
+
57
+ class CAPP008Error < CAPPError
58
+ def initialize
59
+ @da = "Din nøgleapp kunne ikke blive aktiveret, da venteperioden ikke er uløbet."
60
+ @en = "Your code app could not be activated as the waiting period has not expired."
61
+ super
62
+ end
63
+ end
64
+
65
+ class CAPP009Error < CAPPError
66
+ def initialize
67
+ @da = "Din nøgleapp kunne ikke blive aktiveret, da venteperioden ikke er uløbet."
68
+ @en = "Your code app could not be activated as the waiting period has not expired."
69
+ super
70
+ end
71
+ end
72
+
73
+ class CAPP010Error < CAPPError
74
+ def initialize
75
+ @da = "Nulstilling af din nøgeleapps pin kunne ikke blive fuldført, da din nøgleapp ikke er i en aktiv status."
76
+ @en = "The reset of your code app pin could not be done as the code app is not in status active."
77
+ super
78
+ end
79
+ end
80
+
81
+ class CAPP011Error < CAPPError
82
+ def initialize
83
+ @da = "Valideringen af admin action challenge fejlede."
84
+ @en = "The validation of the admin action challenge failed."
85
+ super
86
+ end
87
+ end
88
+
89
+ class CAPP012Error < CAPPError
90
+ def initialize
91
+ @da = "Din nøgleapp kunne ikke blive indskrefvet, da dens app id ikke eksisterer."
92
+ @en = "Your code app could not be enrolled as the code app id does not exist."
93
+ super
94
+ end
95
+ end
96
+
97
+ class CAPP013Error < CAPPError
98
+ def initialize
99
+ @da = "Din nøgleapp kunne ikke blive indskrevet på grund af forkert software fingeraftryk eller manglende whitelist af software fingeraftryk."
100
+ @en = "Your code app could not be enrolled due to incorrect software fingerprint or missing whitelist of software fingerprint"
101
+ super
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,19 @@
1
+ module NemID
2
+ module Errors
3
+ class LIBError < ResponseError
4
+ def initialize(msg='')
5
+ super(msg)
6
+ end
7
+ end
8
+
9
+ class LIB002Error < LIBError
10
+ def initialize
11
+ @da = "Der er opstået en teknisk fejl på grund af netværksproblemer. Forsøg igen. " \
12
+ "Kontakt support, hvis problemet fortsætter."
13
+ @en = "A technical error has occurred due to network issues. Please try again. " \
14
+ "Contact support if the problem persists"
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+ module NemID
2
+ module Errors
3
+ class LOCKError < ResponseError
4
+ DA_SUPPORT_URL = '[https://www.nemid.nu/dk-da/support/faa_hjaelp_til_nemid/kontakt/]'
5
+ EN_SUPPORT_URL = '[https://www.nemid.nu/dk-en/support/contact/]'
6
+
7
+ def initialize(msg='')
8
+ super(msg)
9
+ end
10
+ end
11
+
12
+ class LOCK001Error < LOCKError
13
+ def initialize
14
+ @da = "Du har angivet forkert bruger-id eller adgangskode for mange gange. " \
15
+ "NemID er nu spærret i 8 timer, hvorefter du kan forsøge igen Har du " \
16
+ "glemt din adgangskode kan du finde hjælp her #{DA_SUPPORT_URL}. "
17
+ @en = "You have used the wrong user ID or password too many times. " \
18
+ "Your NemID is now blocked for 8 hours after which you can try again. " \
19
+ "If you have forgotten your password you can find support here " \
20
+ "#{EN_SUPPORT_URL}"
21
+ super
22
+ end
23
+ end
24
+
25
+ class LOCK002Error < LOCKError
26
+ def initialize
27
+ @da = "Du har angivet en forkert adgangskode for mange gange. " \
28
+ "Dit NemID er spærret. Kontakt NemID support for at få adgang til dit " \
29
+ "NemID igen. #{DA_SUPPORT_URL}"
30
+ @en = "You have used a wrong password too many times. Your NemID is " \
31
+ "blocked and cannot be used. To get help with this problem, Please contact " \
32
+ "NemID support. #{EN_SUPPORT_URL}"
33
+ super
34
+ end
35
+ end
36
+
37
+ class LOCK003Error < LOCKError
38
+ def initialize
39
+ @da = "Du har angivet forkert NemID nøgle for mange gange. " \
40
+ "Dit NemID er spærret. Kontakt NemID support for at få adgang til dit " \
41
+ "NemID igen.#{DA_SUPPORT_URL}"
42
+ @en = "You have entered a wrong NemID key too many times. Your NemID is " \
43
+ "blocked and cannot be used. Please contact NemID support. #{EN_SUPPORT_URL}"
44
+ super
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,85 @@
1
+ module NemID
2
+ module Errors
3
+ class OCESError < ResponseError
4
+ def initialize(msg='')
5
+ super(msg)
6
+ end
7
+ end
8
+
9
+ class OCES001Error < OCESError
10
+ def initialize
11
+ @da = "Du har kun NemID til netbank. Ønsker du at bruge NemID til andre " \
12
+ "hjemmesider, skal du tilknytte en offentlig digital signatur til dit NemID. " \
13
+ "[https://service.nemid.nu/dk-da/bestil_nemid/bestil_offentlig_digital_signatur_til_dit_nemid/]."
14
+ @en = "You only have NemID for online banking. If you wish to use NemID for " \
15
+ "other public or private services, you must affiliate a public digital " \
16
+ "signature to your NemID " \
17
+ "[https://service.nemid.nu/dk-da/bestil_nemid/bestil_offentlig_digital_signatur_til_dit_nemid/]"
18
+ super
19
+ end
20
+ end
21
+
22
+ class OCES002Error < OCESError
23
+ def initialize
24
+ @da = "Ønsker du at bruge NemID til andet end netbank, skal du først " \
25
+ "tilknytte en offentlig digital signatur. Det kan du gøre ved at lave en " \
26
+ "almindelig NemID bestilling. " \
27
+ "Bestil NemID [https://service.nemid.nu/dk-da/bestil_nemid/]."
28
+ @en = "If you wish to use NemID for other services than online banking, " \
29
+ "you have to affiliate a public digital signature to your NemID. " \
30
+ "You can do this by starting the regular NemID order flow, which will " \
31
+ "then order the needed public digital signature. " \
32
+ "Request NemID [https://service.nemid.nu/dk-da/bestil_nemid/]"
33
+ super
34
+ end
35
+ end
36
+
37
+ class OCES003Error < OCESError
38
+ def initialize
39
+ @da = "Der er ikke tilknyttet en offentlig digital signatur til " \
40
+ "det NemID du har forsøgt at logge på med. Hvis du tidligere har logget " \
41
+ "ind hos os med NemID, kan fejlen skyldes, at du har flere NemID, og har " \
42
+ "brugt et andet end normalt."
43
+ @en = "You have attempted to log on using a NemID with no public " \
44
+ "digital signature. If you previously have logged on to our service " \
45
+ "using your NemID, the error can be due to having more than one NemID and " \
46
+ "having used a different NemID than normally."
47
+ super
48
+ end
49
+ end
50
+
51
+ class OCES004Error < OCESError
52
+ def initialize
53
+ @da = "Du kan kun bruge dette NemID til netbank."
54
+ @en = "You can only use this NemID for your online banking service."
55
+ super
56
+ end
57
+ end
58
+
59
+ class OCES005Error < OCESError
60
+ def initialize(msg="The service provider is advised to perform a reload of " \
61
+ "the client so the user can try again. Also, if the problem persists, refer to Support.")
62
+ @da = "Udstedelsen af din offentlige digitale signatur mislykkedes. " \
63
+ "Forsøg venligst igen. Hvis problemet fortsætter, kontakt NemID support " \
64
+ "[https://www.nemid.nu/dk-da/support/faa_hjaelp_til_nemid/kontakt/]"
65
+ @en = "Issuing your public digital signature failed. Please try again. " \
66
+ "If the problem persists contact NemID support " \
67
+ "[https://www.nemid.nu/dk-en/support/contact/]"
68
+ super
69
+ end
70
+ end
71
+
72
+ class OCES006Error < OCESError
73
+ def initialize
74
+ @da = "Du har ikke en aktiv offentlig digital signatur tilknyttet " \
75
+ "NemID i øjeblikket. Ved bestilling af NemID vil du blive tilbudt at knytte " \
76
+ "en signatur til dit nuværende NemID. Bestil NemID [https://service.nemid.nu/dk-da/bestil_nemid/]."
77
+ @en = "You currently don’t have an active public digital signature " \
78
+ "(OCES certificate) affiliated with your NemID. To get this, start the regular " \
79
+ "NemID order flow after which you will be asked to affiliate a public " \
80
+ "digital signature with your current NemID. Request NemID [https://service.nemid.nu/dk-da/bestil_nemid/]"
81
+ super
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,72 @@
1
+ module NemID
2
+ module Errors
3
+ class SRVError < ResponseError
4
+ def initialize(msg='')
5
+ @da = "Der er opstået en teknisk fejl. Forsøg igen. " \
6
+ "Kontakt support, hvis problemet fortsætter."
7
+ @en = "A technical error has occurred. Please try again. " \
8
+ "Contact support if the problem persists. "
9
+ super(msg)
10
+ end
11
+ end
12
+
13
+ class SRV001Error < SRVError; end
14
+
15
+ class SRV002Error < SRVError; end
16
+
17
+ class SRV003Error < SRVError; end
18
+
19
+ class SRV004Error < SRVError
20
+ def initialize
21
+ super
22
+ @da = "Der er opstået en teknisk fejl. Kontakt NemID support " \
23
+ "[https://www.nemid.nu/dk-da/support/faa_hjaelp_til_nemid/kontakt/]."
24
+ @en = "A technical error has occurred. Please contact NemID support. " \
25
+ "[https://www.nemid.nu/dk-en/support/contact/]"
26
+ end
27
+ end
28
+
29
+ class SRV005Error < SRVError; end
30
+
31
+ class SRV006Error < SRVError
32
+ def initialize
33
+ super
34
+ @da = "Tidsgrænse er overskredet. Forsøg venligst igen."
35
+ @en = "Time limit exceeded. Please try again."
36
+ end
37
+ end
38
+
39
+ class SRV007Error < SRVError
40
+ def initialize
41
+ super
42
+ @da = "Opdater venligst til nyeste version af appen."
43
+ @en = "Please update to the most recent version of the app."
44
+ end
45
+ end
46
+
47
+ class SRV008Error < SRVError
48
+ def initialize(msg='Fix the integration issue.')
49
+ super
50
+ @da = "Der er opstået en teknisk fejl. Kontakt support."
51
+ @en = "A technical error has occurred. Contact support."
52
+ end
53
+ end
54
+
55
+ class SRV010Error < SRVError
56
+ def initialize(msg="There could be a problem with the enrollment of the " \
57
+ "Service Provider’s VOCES certificate or its validity. Contact NemID for support.")
58
+ super
59
+ end
60
+ end
61
+
62
+ class SRV011Error < SRVError
63
+ def initialize(msg="Fix the integration issue. The value specified in the " \
64
+ "TRANSACTION_CONTEXT parameter to the JS Client was longer than the " \
65
+ "allowed 100 characters.")
66
+ super
67
+ @da = "Der er opstået en teknisk fejl. Kontakt support."
68
+ @en = "A technical error has occurred. Contact support."
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,31 @@
1
+ module NemID
2
+ module Errors
3
+ class ResponseValidationError < ResponseError ; end
4
+
5
+ class InvalidSignature < ResponseValidationError
6
+ def initialize(
7
+ msg = "Invalid signature in the XML Document. Data might be altered."
8
+ )
9
+ super(msg)
10
+ end
11
+ end
12
+
13
+ class InvalidCertificateChain < ResponseValidationError
14
+ def initialize(msg = "Invalid certificate chain.")
15
+ super(msg)
16
+ end
17
+ end
18
+
19
+ class UserCertificateExpired < ResponseValidationError
20
+ def initialize(msg = "User certificate has expired.")
21
+ super(msg)
22
+ end
23
+ end
24
+
25
+ class UserCertificateRevoked < ResponseValidationError
26
+ def initialize(msg = "User certificate has been revoked by CA.")
27
+ super(msg)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,81 @@
1
+ require_relative 'ocsp/errors'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ module NemID
6
+ module OCSP
7
+ def self.request subject:, issuer:, ca:
8
+ digest = OpenSSL::Digest::SHA1.new
9
+ certificate_id = OpenSSL::OCSP::CertificateId.new(subject, issuer, digest)
10
+
11
+ request = OpenSSL::OCSP::Request.new
12
+ request.add_certid(certificate_id)
13
+ request.add_nonce
14
+
15
+ ocsp_uris = subject.ocsp_uris
16
+ ocsp_uri = URI ocsp_uris[0]
17
+
18
+ http_response = Net::HTTP.start ocsp_uri.hostname do |http|
19
+ http.post ocsp_uri.path, request.to_der,
20
+ 'content-type' => 'application/ocsp-request'
21
+ end
22
+
23
+ response = OpenSSL::OCSP::Response.new http_response.body
24
+ response_basic = response.basic
25
+
26
+ response_has_valid_signature?(response_basic, subject, issuer, ca)
27
+
28
+ single_response = response_basic.find_response(certificate_id)
29
+
30
+ response_has_status_and_is_valid?(single_response)
31
+
32
+ raise NonceError if request.check_nonce(response_basic) == 0
33
+
34
+ return cert_status(single_response)
35
+ end
36
+
37
+ private
38
+
39
+ # Returns +true+ if the certificate has been revoked or its unknown,
40
+ # +false+ otherwise.
41
+ def self.cert_status(single_response)
42
+ case single_response.cert_status
43
+ when OpenSSL::OCSP::V_CERTSTATUS_GOOD
44
+ return false
45
+ when OpenSSL::OCSP::V_CERTSTATUS_REVOKED
46
+ return true
47
+ when OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
48
+ return true
49
+ end
50
+ end
51
+
52
+ def self.check_validity(single_response)
53
+ unless single_response.check_validity
54
+ raise InvalidUpdateError
55
+ end
56
+
57
+ return true
58
+ end
59
+
60
+ def self.response_has_status_and_is_valid?(single_response)
61
+ unless single_response
62
+ raise NoStatusError
63
+ end
64
+
65
+ return check_validity(single_response)
66
+ end
67
+
68
+ def self.response_has_valid_signature?(response_basic, subject, issuer, ca)
69
+ store = OpenSSL::X509::Store.new
70
+ store.add_cert(subject)
71
+ store.add_cert(issuer)
72
+ store.add_cert(ca)
73
+
74
+ unless response_basic.verify [], store then
75
+ raise InvalidSignatureError
76
+ end
77
+
78
+ return true
79
+ end
80
+ end
81
+ end