krypt 0.0.1

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.
Files changed (70) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +82 -0
  3. data/lib/krypt.rb +49 -0
  4. data/lib/krypt/asn1.rb +3 -0
  5. data/lib/krypt/asn1/common.rb +96 -0
  6. data/lib/krypt/asn1/template.rb +257 -0
  7. data/lib/krypt/codec.rb +57 -0
  8. data/lib/krypt/codec/base64.rb +140 -0
  9. data/lib/krypt/codec/base_codec.rb +36 -0
  10. data/lib/krypt/codec/hex.rb +122 -0
  11. data/lib/krypt/digest.rb +112 -0
  12. data/lib/krypt/hmac.rb +69 -0
  13. data/lib/krypt/pkcs5.rb +1 -0
  14. data/lib/krypt/pkcs5/pbkdf2.rb +41 -0
  15. data/lib/krypt/provider.rb +35 -0
  16. data/lib/krypt/x509.rb +3 -0
  17. data/lib/krypt/x509/certificate.rb +36 -0
  18. data/lib/krypt/x509/common.rb +41 -0
  19. data/lib/krypt/x509/crl.rb +33 -0
  20. data/lib/krypt_missing.rb +32 -0
  21. data/spec/krypt-core/MEMO.txt +85 -0
  22. data/spec/krypt-core/asn1/asn1_bit_string_spec.rb +475 -0
  23. data/spec/krypt-core/asn1/asn1_boolean_spec.rb +392 -0
  24. data/spec/krypt-core/asn1/asn1_constants_spec.rb +71 -0
  25. data/spec/krypt-core/asn1/asn1_data_spec.rb +1153 -0
  26. data/spec/krypt-core/asn1/asn1_end_of_contents_spec.rb +133 -0
  27. data/spec/krypt-core/asn1/asn1_enumerated_spec.rb +458 -0
  28. data/spec/krypt-core/asn1/asn1_generalized_time_spec.rb +492 -0
  29. data/spec/krypt-core/asn1/asn1_integer_spec.rb +557 -0
  30. data/spec/krypt-core/asn1/asn1_null_spec.rb +360 -0
  31. data/spec/krypt-core/asn1/asn1_object_id_spec.rb +495 -0
  32. data/spec/krypt-core/asn1/asn1_octet_string_spec.rb +456 -0
  33. data/spec/krypt-core/asn1/asn1_parser_spec.rb +503 -0
  34. data/spec/krypt-core/asn1/asn1_pem_spec.rb +282 -0
  35. data/spec/krypt-core/asn1/asn1_sequence_spec.rb +637 -0
  36. data/spec/krypt-core/asn1/asn1_set_spec.rb +795 -0
  37. data/spec/krypt-core/asn1/asn1_utc_time_spec.rb +495 -0
  38. data/spec/krypt-core/asn1/asn1_utf8_string_spec.rb +404 -0
  39. data/spec/krypt-core/asn1/resources.rb +53 -0
  40. data/spec/krypt-core/base64/base64_spec.rb +97 -0
  41. data/spec/krypt-core/digest/digest_spec.rb +707 -0
  42. data/spec/krypt-core/hex/hex_spec.rb +102 -0
  43. data/spec/krypt-core/pem/pem_decode_spec.rb +235 -0
  44. data/spec/krypt-core/resources.rb +1 -0
  45. data/spec/krypt-core/template/template_choice_parse_spec.rb +289 -0
  46. data/spec/krypt-core/template/template_dsl_spec.rb +351 -0
  47. data/spec/krypt-core/template/template_seq_of_parse_spec.rb +64 -0
  48. data/spec/krypt-core/template/template_seq_parse_spec.rb +1241 -0
  49. data/spec/krypt/codec/base64_decoder_spec.rb +94 -0
  50. data/spec/krypt/codec/base64_encoder_spec.rb +94 -0
  51. data/spec/krypt/codec/base64_mixed_spec.rb +16 -0
  52. data/spec/krypt/codec/hex_decoder_spec.rb +94 -0
  53. data/spec/krypt/codec/hex_encoder_spec.rb +94 -0
  54. data/spec/krypt/codec/hex_mixed_spec.rb +17 -0
  55. data/spec/krypt/codec/identity_shared.rb +119 -0
  56. data/spec/krypt/hmac/hmac_spec.rb +311 -0
  57. data/spec/krypt/pkcs5/pbkdf2_spec.rb +79 -0
  58. data/spec/krypt/provider/provider_spec.rb +83 -0
  59. data/spec/res/ca-bundle.crt +11758 -0
  60. data/spec/res/certificate.cer +0 -0
  61. data/spec/res/certificate.pem +20 -0
  62. data/spec/res/multiple_certs.pem +60 -0
  63. data/spec/resources.rb +66 -0
  64. data/test/helper.rb +8 -0
  65. data/test/res/certificate.cer +0 -0
  66. data/test/resources.rb +48 -0
  67. data/test/scratch.rb +28 -0
  68. data/test/test_krypt_asn1.rb +119 -0
  69. data/test/test_krypt_parser.rb +331 -0
  70. metadata +134 -0
Binary file
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
4
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
5
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
6
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
7
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
8
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
9
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
10
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
11
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
12
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
13
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
14
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
15
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
16
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
17
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
18
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
19
+ z+64/9KqwBAeA66J6k7l7C0=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,60 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
4
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
5
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
6
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
7
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
8
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
9
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
10
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
11
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
12
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
13
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
14
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
15
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
16
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
17
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
18
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
19
+ z+64/9KqwBAeA66J6k7l7C0=
20
+ -----END CERTIFICATE-----
21
+ -----BEGIN CERTIFICATE-----
22
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
23
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
24
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
25
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
26
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
27
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
28
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
29
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
30
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
31
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
32
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
33
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
34
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
35
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
36
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
37
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
38
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
39
+ z+64/9KqwBAeA66J6k7l7C0=
40
+ -----END CERTIFICATE-----
41
+ -----BEGIN CERTIFICATE-----
42
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
43
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
44
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
45
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
46
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
47
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
48
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
49
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
50
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
51
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
52
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
53
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
54
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
55
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
56
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
57
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
58
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
59
+ z+64/9KqwBAeA66J6k7l7C0=
60
+ -----END CERTIFICATE-----
@@ -0,0 +1,66 @@
1
+ require 'openssl'
2
+
3
+ module Resources
4
+
5
+ CERTIFICATE_PEM = <<-_EOF_
6
+ -----BEGIN CERTIFICATE-----
7
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
8
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
9
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
10
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
11
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
12
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
13
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
14
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
15
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
16
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
17
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
18
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
19
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
20
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
21
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
22
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
23
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
24
+ z+64/9KqwBAeA66J6k7l7C0=
25
+ -----END CERTIFICATE-----
26
+ _EOF_
27
+
28
+ CERTIFICATE = OpenSSL::X509::Certificate.new CERTIFICATE_PEM
29
+
30
+ class << self
31
+ def certificate
32
+ CERTIFICATE.to_der
33
+ end
34
+
35
+ def certificate_pem
36
+ CERTIFICATE_PEM
37
+ end
38
+
39
+ def certificate_io
40
+ File.open(File.expand_path('res/certificate.cer', File.dirname(__FILE__)), "rb")
41
+ end
42
+
43
+ def certificate_pem_io
44
+ File.open(File.expand_path('res/certificate.pem', File.dirname(__FILE__)), "rb")
45
+ end
46
+
47
+ def multi_certificate_pem_io
48
+ File.open(File.expand_path('res/multiple_certs.pem', File.dirname(__FILE__)), "rb")
49
+ end
50
+
51
+ def ca_certificate_pem_io
52
+ File.open(File.expand_path('res/ca-bundle.crt', File.dirname(__FILE__)), "rb")
53
+ end
54
+
55
+ def bytes_to_io(str)
56
+ raw = [str.join('')].pack('H*')
57
+ StringIO.new raw
58
+ end
59
+
60
+ def bytes(str)
61
+ [str.join('')].pack('H*')
62
+ end
63
+ end
64
+
65
+ end
66
+
@@ -0,0 +1,8 @@
1
+ begin
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ rescue LoadError
5
+ end
6
+ require 'krypt'
7
+ require 'test/unit'
8
+ require_relative 'resources'
Binary file
@@ -0,0 +1,48 @@
1
+ require 'openssl'
2
+
3
+ module Resources
4
+
5
+ CERTIFICATE = OpenSSL::X509::Certificate.new <<-_EOF_
6
+ -----BEGIN CERTIFICATE-----
7
+ MIIDPTCCAiWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADA9MRMwEQYKCZImiZPyLGQB
8
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
9
+ Fw0xMTEwMjkxNTM2MzJaFw0xMTEwMjkxNjA2MzJaMD4xEzARBgoJkiaJk/IsZAEZ
10
+ FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxDDAKBgNVBAMMA0VFMjCB
11
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8At
12
+ v5y/OVQRp0ag8Tqo1YewsWijxEWB7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9J
13
+ Wsjah8ssEBFSxZqdXKSLf0N4Hi7/GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/p
14
+ eeBOpRfyXxRFOYcCAwEAAaOByjCBxzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
15
+ FNH++fv4rhvBYMv6A+JZbdhzCJITME8GA1UdIwRIMEahQaQ/MD0xEzARBgoJkiaJ
16
+ k/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMM
17
+ AkNBggEBMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDBAYIKwYBBQUHAwMw
18
+ HAYDVR0RBBUwE4ERZWUyQHJ1YnktbGFuZy5vcmcwDQYJKoZIhvcNAQEEBQADggEB
19
+ ABLJKAS9nXFI3idP3dXXs8n4gLBrWHyaacklwnj8gvVoNtYQIICXODY/zQLtzfjx
20
+ SQxlrOUtn0uYTzJUNc+NLfc8EzcVDhmSWhq+msCFEyhL5+kBceFj2ZI8f9OuQ87m
21
+ zy1yqE1jxP1fsGDZ3Cqny86jJvwRzPW6NkPtkFzS6ZYe09DXDZnUuZP8kVpn4Pit
22
+ vHmj/XVKl4LGxlrebReqIn+m2K46uxUkQEDhk7R16SAl6N92W7vI/lXr98aVdfF4
23
+ Ozmrzopvt+XbjtvJztDNhpG0G/celhgAOzNx/eq3wl89qHIa+9vvVbFZ0BdYUHai
24
+ z+64/9KqwBAeA66J6k7l7C0=
25
+ -----END CERTIFICATE-----
26
+ _EOF_
27
+
28
+ class << self
29
+ def certificate
30
+ CERTIFICATE.to_der
31
+ end
32
+
33
+ def certificate_io
34
+ File.new(File.expand_path('res/certificate.cer', File.dirname(__FILE__)))
35
+ end
36
+
37
+ def bytes_to_io(str)
38
+ raw = [str.join('')].pack('H*')
39
+ StringIO.new raw
40
+ end
41
+
42
+ def bytes(str)
43
+ [str.join('')].pack('H*')
44
+ end
45
+ end
46
+
47
+ end
48
+
@@ -0,0 +1,28 @@
1
+ # encoding: US-ASCII
2
+ require 'krypt'
3
+ require_relative 'resources'
4
+ require 'openssl'
5
+ require 'stringio'
6
+ require 'pp'
7
+
8
+ decoder = Krypt::ASN1
9
+
10
+ stringio = StringIO.new(
11
+ [
12
+ Krypt::ASN1::Null.new,
13
+ Krypt::ASN1::Integer.new(0)
14
+ ].map { |e| e.to_der }.join
15
+ )
16
+ c = Class.new do
17
+ def initialize(io)
18
+ @io = io
19
+ end
20
+
21
+ def read(*args)
22
+ @io.read(*args)
23
+ end
24
+ end
25
+
26
+ generic = c.new(stringio)
27
+ p decoder.decode_der(generic)
28
+ p decoder.decode_der(generic)
@@ -0,0 +1,119 @@
1
+ require_relative 'helper'
2
+ require 'stringio'
3
+
4
+ class Krypt::ASN1Test < Test::Unit::TestCase
5
+
6
+ def test_parse_encode_equality_file
7
+ io = Resources.certificate_io
8
+ begin
9
+ asn1 = Krypt::ASN1.decode(io)
10
+ cert = Resources.certificate
11
+ assert_equal(cert, asn1.to_der)
12
+ assert_equal_streaming(cert, asn1)
13
+ ensure
14
+ io.close
15
+ end
16
+ end
17
+
18
+ def test_parse_encode_equality_string_io
19
+ io = StringIO.new(Resources.certificate)
20
+ asn1 = Krypt::ASN1.decode(io)
21
+ cert = Resources.certificate
22
+ assert_equal(cert, asn1.to_der)
23
+ assert_equal_streaming(cert, asn1)
24
+ end
25
+
26
+ def test_parse_encode_equality_string
27
+ asn1 = Krypt::ASN1.decode(Resources.certificate)
28
+ cert = Resources.certificate
29
+ assert_equal(cert, asn1.to_der)
30
+ assert_equal_streaming(cert, asn1)
31
+ end
32
+
33
+ def test_attributes
34
+ raw = [%w{30 06 04 01 01 02 01 01}.join("")].pack("H*")
35
+ asn1 = Krypt::ASN1.decode(raw)
36
+ assert_universal(Krypt::ASN1::SEQUENCE, asn1)
37
+ seq = asn1.value
38
+ assert_equal(2, seq.size)
39
+ octet = seq[0]
40
+ assert_universal(Krypt::ASN1::OCTET_STRING, octet)
41
+ assert_equal("\1", octet.value)
42
+ integer = seq[1]
43
+ assert_universal(Krypt::ASN1::INTEGER, integer)
44
+ assert_equal(1, integer.value)
45
+
46
+ assert_equal(raw, asn1.to_der)
47
+ end
48
+
49
+ def test_parse_infinite_length_sequence
50
+ raw = [%w{30 80 04 01 01 02 01 01 00 00}.join("")].pack("H*")
51
+ asn1 = Krypt::ASN1.decode(raw)
52
+ assert_universal(Krypt::ASN1::SEQUENCE, asn1, true)
53
+ seq = asn1.value
54
+ assert_equal(3, seq.size)
55
+ octet = seq[0]
56
+ assert_universal(Krypt::ASN1::OCTET_STRING, octet)
57
+ assert_equal("\1", octet.value)
58
+ integer = seq[1]
59
+ assert_universal(Krypt::ASN1::INTEGER, integer)
60
+ assert_equal(1, integer.value)
61
+ eoc = seq[2]
62
+ assert_universal(Krypt::ASN1::END_OF_CONTENTS, eoc)
63
+ assert_nil(eoc.value)
64
+
65
+ assert_equal(raw, asn1.to_der)
66
+ end
67
+
68
+ def test_parse_infinite_length_octet_string
69
+ raw = [%w{24 80 04 01 01 04 01 02 00 00}.join("")].pack("H*")
70
+ asn1 = Krypt::ASN1.decode(raw)
71
+ assert_universal(Krypt::ASN1::OCTET_STRING, asn1, true)
72
+ assert_equal(true, asn1.is_a?(Krypt::ASN1::Constructive))
73
+ seq = asn1.value
74
+ assert_equal(3, seq.size)
75
+ octet1 = seq[0]
76
+ assert_universal(Krypt::ASN1::OCTET_STRING, octet1)
77
+ assert_equal("\1", octet1.value)
78
+ octet2 = seq[1]
79
+ assert_universal(Krypt::ASN1::OCTET_STRING, octet2)
80
+ assert_equal("\2", octet2.value)
81
+ eoc = seq[2]
82
+ assert_universal(Krypt::ASN1::END_OF_CONTENTS, eoc)
83
+ assert_nil(eoc.value)
84
+
85
+ assert_equal(raw, asn1.to_der)
86
+ end
87
+
88
+ def test_each
89
+ [%w{30 06 04 01 01 02 01 01},
90
+ %w{31 06 04 01 01 02 01 01},
91
+ %w{24 80 04 01 01 04 01 02 00 00}].each do |raw|
92
+ val = [raw.join("")].pack("H*")
93
+ cons_header = Krypt::ASN1::Parser.new.next(StringIO.new(val))
94
+ io = StringIO.new
95
+ cons_header.encode_to(io)
96
+ asn1 = Krypt::ASN1.decode(val)
97
+ asn1.each do |val|
98
+ val.encode_to(io)
99
+ end
100
+ assert_equal(val, io.string.force_encoding("ASCII-8BIT"))
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def assert_universal(tag, asn1, inf_len=false)
107
+ assert_equal(tag, asn1.tag)
108
+ assert_equal(:UNIVERSAL, asn1.tag_class)
109
+ assert_equal(inf_len, asn1.infinite_length)
110
+ end
111
+
112
+ def assert_equal_streaming(raw, asn1)
113
+ io = StringIO.new
114
+ asn1.encode_to(io)
115
+ assert_equal(raw, io.string.force_encoding("ASCII-8BIT"))
116
+ end
117
+
118
+ end
119
+
@@ -0,0 +1,331 @@
1
+ require_relative 'helper'
2
+ require 'stringio'
3
+
4
+ class Krypt::ParserTest < Test::Unit::TestCase
5
+
6
+ def test_parse_and_skip_top_level_file
7
+ parse_and_skip_top_level(Resources.certificate_io)
8
+ end
9
+
10
+ def test_parse_and_skip_top_level_string_io
11
+ parse_and_skip_top_level(StringIO.new(Resources.certificate))
12
+ end
13
+
14
+ def test_parse_and_skip_file
15
+ parse_and_skip(Resources.certificate_io)
16
+ end
17
+
18
+ def test_parse_and_skip_string_io
19
+ parse_and_skip(StringIO.new(Resources.certificate))
20
+ end
21
+
22
+ def test_consume_top_level_streaming_file
23
+ consume_top_level_streaming(Resources.certificate_io)
24
+ end
25
+
26
+ def test_consume_top_level_streaming_string_io
27
+ consume_top_level_streaming(StringIO.new(Resources.certificate))
28
+ end
29
+
30
+ def test_consume_top_level_at_once_file
31
+ consume_top_level_at_once(Resources.certificate_io)
32
+ end
33
+
34
+ def test_consume_top_level_at_once_string_io
35
+ consume_top_level_at_once(StringIO.new(Resources.certificate))
36
+ end
37
+
38
+ def test_consume_all_streaming_file
39
+ consume_all_streaming(Resources.certificate_io)
40
+ end
41
+
42
+ def test_consume_all_streaming_string_io
43
+ consume_all_streaming(StringIO.new(Resources.certificate))
44
+ end
45
+
46
+ def test_consume_all_at_once_file
47
+ consume_all_at_once(Resources.certificate_io)
48
+ end
49
+
50
+ def test_consume_all_at_once_string_io
51
+ consume_all_at_once(StringIO.new(Resources.certificate))
52
+ end
53
+
54
+ def test_parse_tokens_methods_file
55
+ parse_tokens_test_methods(Resources.certificate_io)
56
+ end
57
+
58
+ def test_parse_tokens_methods_string_io
59
+ parse_tokens_test_methods(StringIO.new(Resources.certificate))
60
+ end
61
+
62
+ def test_parse_primitive
63
+ raw = [%w{02 02 01 00}.join("")].pack("H*")
64
+ parser = Krypt::ASN1::Parser.new
65
+ io = StringIO.new(raw)
66
+ header = parser.next(io)
67
+ assert_equal(Krypt::ASN1::INTEGER, header.tag)
68
+ assert_equal(:UNIVERSAL, header.tag_class)
69
+ assert_equal(false, header.constructed?)
70
+ assert_equal(false, header.infinite?)
71
+ assert_equal(2, header.length)
72
+ assert_equal(2, header.header_length)
73
+ assert_header_value_equal(raw, header)
74
+ end
75
+
76
+ def test_parse_constructed
77
+ raw = [%w{30 06 04 01 01 04 01 02}.join("")].pack("H*")
78
+ parser = Krypt::ASN1::Parser.new
79
+ io = StringIO.new(raw)
80
+ header = parser.next(io)
81
+ assert_equal(Krypt::ASN1::SEQUENCE, header.tag)
82
+ assert_equal(:UNIVERSAL, header.tag_class)
83
+ assert_equal(true, header.constructed?)
84
+ assert_equal(false, header.infinite?)
85
+ assert_equal(6, header.length)
86
+ assert_equal(2, header.header_length)
87
+ assert_header_value_equal(raw, header)
88
+ end
89
+
90
+ def test_parse_constructed
91
+ raw = [%w{30 02 80 01 00}.join("")].pack("H*")
92
+ parser = Krypt::ASN1::Parser.new
93
+ io = StringIO.new(raw)
94
+ header = parser.next(io)
95
+ assert_equal(Krypt::ASN1::SEQUENCE, header.tag)
96
+ assert_equal(:UNIVERSAL, header.tag_class)
97
+ assert_equal(true, header.constructed?)
98
+ assert_equal(false, header.infinite?)
99
+ assert_equal(2, header.length)
100
+ assert_equal(2, header.header_length)
101
+ header = parser.next(io)
102
+ assert_equal(0, header.tag)
103
+ assert_equal(:CONTEXT_SPECIFIC, header.tag_class)
104
+ assert_equal(false, header.constructed?)
105
+ assert_equal(false, header.infinite?)
106
+ assert_equal(1, header.length)
107
+ assert_equal(2, header.header_length)
108
+ assert_equal("\0", header.value)
109
+ assert_nil(parser.next(io))
110
+ end
111
+
112
+ def test_complex_length
113
+ raw = [%w{04 82 03 e8}.join("")].pack("H*")
114
+ raw << "\0" * 1000
115
+ io = StringIO.new(raw)
116
+ parser = Krypt::ASN1::Parser.new
117
+ header = parser.next(io)
118
+ assert_equal(Krypt::ASN1::OCTET_STRING, header.tag)
119
+ assert_equal(:UNIVERSAL, header.tag_class)
120
+ assert_equal(false, header.constructed?)
121
+ assert_equal(false, header.infinite?)
122
+ assert_equal(1000, header.length)
123
+ assert_equal(4, header.header_length)
124
+ assert_header_value_equal(raw, header)
125
+ end
126
+
127
+ def test_complex_length_single_octet
128
+ raw = [%w{df 2a 01 00}.join("")].pack("H*")
129
+ parser = Krypt::ASN1::Parser.new
130
+ io = StringIO.new(raw)
131
+ header = parser.next(io)
132
+ assert_equal(42, header.tag)
133
+ assert_equal(:PRIVATE, header.tag_class)
134
+ assert_equal(false, header.constructed?)
135
+ assert_equal(false, header.infinite?)
136
+ assert_equal(1, header.length)
137
+ assert_equal(3, header.header_length)
138
+ assert_header_value_equal(raw, header)
139
+ end
140
+
141
+ def test_complex_tag_two_octets
142
+ raw = [%w{5f 82 2c 01 00}.join("")].pack("H*")
143
+ parser = Krypt::ASN1::Parser.new
144
+ io = StringIO.new(raw)
145
+ header = parser.next(io)
146
+ assert_equal(300, header.tag)
147
+ assert_equal(:APPLICATION, header.tag_class)
148
+ assert_equal(false, header.constructed?)
149
+ assert_equal(false, header.infinite?)
150
+ assert_equal(1, header.length)
151
+ assert_equal(4, header.header_length)
152
+ assert_header_value_equal(raw, header)
153
+ end
154
+
155
+ def test_inf_length_parsing_at_once_string_io
156
+ inf_length_parsing_streaming_string_io(:AT_ONCE)
157
+ end
158
+
159
+ def test_inf_length_parsing_streaming_string_io
160
+ inf_length_parsing_streaming_string_io(:STREAMING)
161
+ end
162
+
163
+ def test_inf_length_parsing_streaming_fixed_buffer_string_io
164
+ inf_length_parsing_streaming_string_io(:STREAMING_FIXED)
165
+ end
166
+
167
+ def test_inf_length_parsing_at_once_values_only_string_io
168
+ inf_length_parsing_streaming_string_io(:AT_ONCE, true)
169
+ end
170
+
171
+ def test_inf_length_parsing_streaming_values_only_string_io
172
+ inf_length_parsing_streaming_string_io(:STREAMING, true)
173
+ end
174
+
175
+ def test_inf_length_parsing_streaming_fixed_buffer_values_only_string_io
176
+ inf_length_parsing_streaming_string_io(:STREAMING_FIXED, true)
177
+ end
178
+
179
+ private
180
+
181
+ def parse_and_skip_top_level(io)
182
+ parser = Krypt::ASN1::Parser.new
183
+ header = parser.next(io)
184
+ assert_equal(Krypt::ASN1::SEQUENCE, header.tag)
185
+ assert_equal(:UNIVERSAL, header.tag_class)
186
+ assert(header.constructed?)
187
+ assert(!header.infinite?)
188
+ assert_equal(Resources.certificate.size, header.header_size + header.size)
189
+ header.skip_value
190
+ assert_nil(parser.next(io))
191
+ ensure
192
+ io.close
193
+ end
194
+
195
+ def parse_and_skip(io)
196
+ parser = Krypt::ASN1::Parser.new
197
+ num_tokens = 0
198
+ while header = parser.next(io)
199
+ num_tokens += 1
200
+ unless header.constructed?
201
+ header.skip_value
202
+ end
203
+ end
204
+ assert(num_tokens > 1)
205
+ ensure
206
+ io.close
207
+ end
208
+
209
+ def consume_top_level_streaming(io)
210
+ parser = Krypt::ASN1::Parser.new
211
+ header = parser.next(io)
212
+ stream = header.value_io
213
+ consume_streaming(stream)
214
+ assert_nil(parser.next(io))
215
+ ensure
216
+ io.close
217
+ end
218
+
219
+ def consume_top_level_at_once(io)
220
+ parser = Krypt::ASN1::Parser.new
221
+ header = parser.next(io)
222
+ stream = header.value_io
223
+ stream.read
224
+ assert_nil(parser.next(io))
225
+ ensure
226
+ io.close
227
+ end
228
+
229
+ def consume_all_streaming(io)
230
+ parser = Krypt::ASN1::Parser.new
231
+ while header = parser.next(io)
232
+ unless header.constructed?
233
+ stream = header.value_io
234
+ consume_streaming(stream)
235
+ end
236
+ end
237
+ assert_nil(parser.next(io))
238
+ ensure
239
+ io.close
240
+ end
241
+
242
+ def consume_all_at_once(io)
243
+ parser = Krypt::ASN1::Parser.new
244
+ while header = parser.next(io)
245
+ unless header.constructed?
246
+ stream = header.value_io
247
+ stream.read
248
+ end
249
+ end
250
+ assert_nil(parser.next(io))
251
+ ensure
252
+ io.close
253
+ end
254
+
255
+ def parse_tokens_test_methods(io)
256
+ parser = Krypt::ASN1::Parser.new
257
+ while header = parser.next(io)
258
+ assert_not_nil(header.tag)
259
+ assert_not_nil(header.tag_class)
260
+ assert_not_nil(header.size)
261
+ assert_not_nil(header.length)
262
+ assert_not_nil(header.header_size)
263
+ assert_not_nil(header.header_length)
264
+ assert_not_nil(header.constructed?)
265
+ assert_not_nil(header.infinite?)
266
+ unless header.constructed?
267
+ if (header.tag == Krypt::ASN1::NULL || header.tag == Krypt::ASN1::END_OF_CONTENTS)
268
+ assert_nil(header.value)
269
+ else
270
+ assert_not_nil(header.value)
271
+ end
272
+ end
273
+ end
274
+ ensure
275
+ io.close
276
+ end
277
+
278
+ def inf_length_parsing_streaming_string_io(mode, values_only=false)
279
+ raw = [%w{24 80 04 01 01 04 01 02 00 00}.join("")].pack("H*")
280
+ io = StringIO.new(raw)
281
+ parser = Krypt::ASN1::Parser.new
282
+ header = parser.next(io)
283
+ assert_equal(Krypt::ASN1::OCTET_STRING, header.tag)
284
+ assert_equal(:UNIVERSAL, header.tag_class)
285
+ assert_equal(true, header.constructed?)
286
+ assert_equal(true, header.infinite?)
287
+ assert_equal(0, header.length)
288
+ assert_equal(2, header.header_length)
289
+ value_io = header.value_io(values_only)
290
+
291
+ result = StringIO.new("", "wb")
292
+ unless values_only
293
+ header.encode_to(result)
294
+ end
295
+
296
+ case mode
297
+ when :AT_ONCE
298
+ result << value_io.read
299
+ when :STREAMING
300
+ while buf = value_io.read(3, buf)
301
+ result << buf
302
+ end
303
+ when :STREAMING_FIXED
304
+ buf = ""
305
+ while value_io.read(3, buf)
306
+ result << buf
307
+ end
308
+ end
309
+
310
+ if values_only
311
+ assert_equal( [%w{01 02}.join("")].pack("H*"), result.string)
312
+ else
313
+ assert_equal(raw, result.string.force_encoding("ASCII-8BIT"))
314
+ end
315
+ end
316
+
317
+ def consume_streaming(io)
318
+ buffer = ""
319
+ while io.read(3, buffer)
320
+ end
321
+ end
322
+
323
+ def assert_header_value_equal(expected, header)
324
+ io = StringIO.new()
325
+ header.encode_to(io)
326
+ io << header.value
327
+ assert_equal(expected, io.string.force_encoding("ASCII-8BIT"))
328
+ end
329
+
330
+ end
331
+