rasn1 0.6.1 → 0.6.2
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.
- checksums.yaml +5 -5
- data/.travis.yml +4 -3
- data/README.md +1 -1
- data/lib/rasn1/types.rb +2 -0
- data/lib/rasn1/types/generalized_time.rb +111 -0
- data/lib/rasn1/types/utc_time.rb +53 -0
- data/lib/rasn1/version.rb +1 -1
- data/rasn1.gemspec +4 -1
- metadata +9 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a9745a1fe5540da0693f4e9bf5048dd177c58e314917e6d606b1caa34fa0f138
|
|
4
|
+
data.tar.gz: 67f2bc01529e894be272fb905ded771a89f8bb6eb14bc1eac86178d3e7a72148
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc403f68a96560969a2221bc255e9f9f56dacb90f174977067054830dd0b85afc53dd8c25b130ddda3d38b6fc8e3d9d6341e9e5a805dda59ea4b478d3b960a78
|
|
7
|
+
data.tar.gz: 201e5f5255a2ebb2a2d26c9fe2a75d9fed7f72d5e32f6ceb712e4ff0d01c81b38a896c31ee6bf446f74b9065f5ef6bab5cecdbf55e236dc53b53015ee959ee58
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
data/lib/rasn1/types.rb
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
module RASN1
|
|
2
|
+
module Types
|
|
3
|
+
|
|
4
|
+
# ASN.1 GeneralizedTime
|
|
5
|
+
#
|
|
6
|
+
# +{#value} of a {GeneralizedTime} should be a ruby Time.
|
|
7
|
+
#
|
|
8
|
+
# ===Notes
|
|
9
|
+
# When encoding, resulting string is always a UTC time, appended with +Z+.
|
|
10
|
+
# Minutes and seconds are always generated. Fractions of second are generated
|
|
11
|
+
# if value Time object have them.
|
|
12
|
+
#
|
|
13
|
+
# On parsing, are supported:
|
|
14
|
+
# * UTC times (ending with +Z+),
|
|
15
|
+
# * local times (no suffix),
|
|
16
|
+
# * local times with difference between UTC and this local time (ending with
|
|
17
|
+
# +sHHMM+, where +s+ is +++ or +-+, and +HHMM+ is the time differential
|
|
18
|
+
# betwen UTC and local time).
|
|
19
|
+
# These times may include minutes and seconds. Fractions of hour, minute and
|
|
20
|
+
# second are supported.
|
|
21
|
+
# @author Sylvain Daubert
|
|
22
|
+
class GeneralizedTime < Primitive
|
|
23
|
+
TAG = 24
|
|
24
|
+
|
|
25
|
+
# Get ASN.1 type
|
|
26
|
+
# @return [String]
|
|
27
|
+
def self.type
|
|
28
|
+
'GeneralizedTime'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def value_to_der
|
|
34
|
+
if @value.nsec > 0
|
|
35
|
+
der = @value.getutc.strftime('%Y%m%d%H%M%S.%9NZ')
|
|
36
|
+
der.sub(/0+Z/, 'Z')
|
|
37
|
+
else
|
|
38
|
+
@value.getutc.strftime('%Y%m%d%H%M%SZ')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def der_to_value(der, ber: false)
|
|
43
|
+
date_hour, fraction = der.split('.')
|
|
44
|
+
utc_offset_forced = false
|
|
45
|
+
if fraction.nil?
|
|
46
|
+
if date_hour[-1] != 'Z' and date_hour !~ /[+-]\d+$/
|
|
47
|
+
# If not UTC, have to add offset with UTC to force
|
|
48
|
+
# DateTime#strptime to generate a local time. But this difference
|
|
49
|
+
# may be errored because of DST.
|
|
50
|
+
date_hour << Time.now.strftime('%z')
|
|
51
|
+
utc_offset_forced = true
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
if fraction[-1] == 'Z'
|
|
55
|
+
fraction = fraction[0...-1]
|
|
56
|
+
date_hour << 'Z'
|
|
57
|
+
else
|
|
58
|
+
match = fraction.match(/(\d+)([+-]\d+)/)
|
|
59
|
+
if match
|
|
60
|
+
# fraction contains fraction and timezone info. Split them
|
|
61
|
+
fraction = match[1]
|
|
62
|
+
date_hour << match[2]
|
|
63
|
+
else
|
|
64
|
+
# fraction only contains fraction.
|
|
65
|
+
# Have to add offset with UTC to force DateTime#strptime to
|
|
66
|
+
# generate a local time. But this difference may be errored
|
|
67
|
+
# because of DST.
|
|
68
|
+
date_hour << Time.now.strftime('%z')
|
|
69
|
+
utc_offset_forced = true
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
format = case date_hour.size
|
|
74
|
+
when 11
|
|
75
|
+
frac_base = 60*60
|
|
76
|
+
'%Y%m%d%HZ'
|
|
77
|
+
when 13
|
|
78
|
+
frac_base = 60
|
|
79
|
+
'%Y%m%d%H%MZ'
|
|
80
|
+
when 15
|
|
81
|
+
if date_hour[-1] == 'Z'
|
|
82
|
+
frac_base = 1
|
|
83
|
+
'%Y%m%d%H%M%SZ'
|
|
84
|
+
else
|
|
85
|
+
frac_base = 60 * 60
|
|
86
|
+
'%Y%m%d%H%z'
|
|
87
|
+
end
|
|
88
|
+
when 17
|
|
89
|
+
frac_base = 60
|
|
90
|
+
'%Y%m%d%H%M%z'
|
|
91
|
+
when 19
|
|
92
|
+
frac_base = 1
|
|
93
|
+
'%Y%m%d%H%M%S%z'
|
|
94
|
+
else
|
|
95
|
+
prefix = @name.nil? ? type : "tag #{@name}"
|
|
96
|
+
raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
|
|
97
|
+
end
|
|
98
|
+
@value = DateTime.strptime(date_hour, format).to_time
|
|
99
|
+
# local time format.
|
|
100
|
+
# Check DST. There may be a shift of one hour...
|
|
101
|
+
if utc_offset_forced
|
|
102
|
+
compare_time = Time.new(*@value.to_a[0..5].reverse)
|
|
103
|
+
if compare_time.utc_offset != @value.utc_offset
|
|
104
|
+
@value = compare_time
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
@value += ".#{fraction}".to_r * frac_base unless fraction.nil?
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'date'
|
|
2
|
+
|
|
3
|
+
module RASN1
|
|
4
|
+
module Types
|
|
5
|
+
|
|
6
|
+
# ASN.1 UTCTime
|
|
7
|
+
#
|
|
8
|
+
# +{#value} of a +UtcTime+ should be a ruby Time.
|
|
9
|
+
#
|
|
10
|
+
# ===Notes
|
|
11
|
+
# When encoding, resulting string is always a UTC time, appended with +Z+.
|
|
12
|
+
# Seconds are always generated.
|
|
13
|
+
#
|
|
14
|
+
# On parsing, UTC times (ending with +Z+) and local times (ending with
|
|
15
|
+
# +sHHMM+, where +s+ is +++ or +-+, and +HHMM+ is the time differential
|
|
16
|
+
# betwen UTC and local time) are both supported. Seconds may be present or
|
|
17
|
+
# not.
|
|
18
|
+
# @author Sylvain Daubert
|
|
19
|
+
class UtcTime < Primitive
|
|
20
|
+
TAG = 23
|
|
21
|
+
|
|
22
|
+
# Get ASN.1 type
|
|
23
|
+
# @return [String]
|
|
24
|
+
def self.type
|
|
25
|
+
'UTCTime'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def value_to_der
|
|
31
|
+
@value.getutc.strftime('%y%m%d%H%M%SZ')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def der_to_value(der, ber: false)
|
|
35
|
+
format = case der.size
|
|
36
|
+
when 11
|
|
37
|
+
'%Y%m%d%H%MZ'
|
|
38
|
+
when 13
|
|
39
|
+
'%Y%m%d%H%M%SZ'
|
|
40
|
+
when 15
|
|
41
|
+
'%Y%m%d%H%M%z'
|
|
42
|
+
when 17
|
|
43
|
+
'%Y%m%d%H%M%S%z'
|
|
44
|
+
else
|
|
45
|
+
prefix = @name.nil? ? type : "tag #{@name}"
|
|
46
|
+
raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
|
|
47
|
+
end
|
|
48
|
+
century = (Time.now.year / 100).to_s
|
|
49
|
+
@value = DateTime.strptime(century + der, format).to_time
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/rasn1/version.rb
CHANGED
data/rasn1.gemspec
CHANGED
|
@@ -11,7 +11,10 @@ Gem::Specification.new do |spec|
|
|
|
11
11
|
spec.email = ['sylvain.daubert@laposte.net']
|
|
12
12
|
|
|
13
13
|
spec.summary = %q{Ruby ASN.1 library}
|
|
14
|
-
|
|
14
|
+
spec.description = %q{
|
|
15
|
+
RASN1 is a pure ruby ASN.1 library. It may encode and decode DER and BER
|
|
16
|
+
encodings.
|
|
17
|
+
}
|
|
15
18
|
spec.homepage = 'https://github.com/sdaubert/rasn1'
|
|
16
19
|
|
|
17
20
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rasn1
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sylvain Daubert
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-05-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: yard
|
|
@@ -80,7 +80,10 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0.14'
|
|
83
|
-
description:
|
|
83
|
+
description: |2
|
|
84
|
+
|
|
85
|
+
RASN1 is a pure ruby ASN.1 library. It may encode and decode DER and BER
|
|
86
|
+
encodings.
|
|
84
87
|
email:
|
|
85
88
|
- sylvain.daubert@laposte.net
|
|
86
89
|
executables: []
|
|
@@ -103,6 +106,7 @@ files:
|
|
|
103
106
|
- lib/rasn1/types/choice.rb
|
|
104
107
|
- lib/rasn1/types/constructed.rb
|
|
105
108
|
- lib/rasn1/types/enumerated.rb
|
|
109
|
+
- lib/rasn1/types/generalized_time.rb
|
|
106
110
|
- lib/rasn1/types/ia5string.rb
|
|
107
111
|
- lib/rasn1/types/integer.rb
|
|
108
112
|
- lib/rasn1/types/null.rb
|
|
@@ -115,6 +119,7 @@ files:
|
|
|
115
119
|
- lib/rasn1/types/sequence_of.rb
|
|
116
120
|
- lib/rasn1/types/set.rb
|
|
117
121
|
- lib/rasn1/types/set_of.rb
|
|
122
|
+
- lib/rasn1/types/utc_time.rb
|
|
118
123
|
- lib/rasn1/types/utf8_string.rb
|
|
119
124
|
- lib/rasn1/types/visible_string.rb
|
|
120
125
|
- lib/rasn1/version.rb
|
|
@@ -139,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
139
144
|
version: '0'
|
|
140
145
|
requirements: []
|
|
141
146
|
rubyforge_project:
|
|
142
|
-
rubygems_version: 2.6
|
|
147
|
+
rubygems_version: 2.7.6
|
|
143
148
|
signing_key:
|
|
144
149
|
specification_version: 4
|
|
145
150
|
summary: Ruby ASN.1 library
|