-
Notifications
You must be signed in to change notification settings - Fork 13.8k
/
types.rb
86 lines (67 loc) · 2.18 KB
/
types.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# -*- coding: binary -*-
require 'rasn1'
module Rex::Proto::CryptoAsn1::Types
class RASN1::Model
def self.bmp_string(name, options = {})
custom_primitive_type_for(name, RASN1::Types::BmpString, options)
end
def self.teletex_string(name, options = {})
strict_encoding = options.fetch(:strict_encoding, true)
options.delete(:strict_encoding)
if strict_encoding
raise NotImplementedError.new('The ITU T.61 codec is not available.')
custom_primitive_type_for(name, TeletexString, options)
else
custom_primitive_type_for(name, TeletexString::Permissive, options)
end
end
def self.universal_string(name, options = {})
custom_primitive_type_for(name, UniversalString, options)
end
def self.custom_primitive_type_for(name, clazz, options = {})
options.merge!(name: name)
proc = proc do |opts|
clazz.new(options.merge(opts))
end
@root = Elem.new(name, proc, nil)
end
private_class_method :custom_primitive_type_for
end
class TeletexString < RASN1::Types::OctetString
ID = 20
def self.type
'TeletexString'
end
ENCODING = 'ITU-T.61'.freeze
# Technically this type should be using T.61 encoding, however some libraries
# such as OpenSSL use this type to label strings encoded with ISO-8859-1.
# See:
# * https://pike.lysator.liu.se/generated/manual/modref/ex/7.8_3A_3A/Standards/ASN1/Types/TeletexString.html
# * https://github.com/wbond/asn1crypto/blob/fad689f2072e405317436c8bf7f6609ba183a060/asn1crypto/x509.py#L461-L465
class Permissive < TeletexString
ENCODING = 'ISO-8859-1'.freeze
end
private
def value_to_der
@value.to_s.dup.encode(self.class::ENCODING).b
end
def der_to_value(der, ber: false)
super
@value = der.dup.force_encoding(self.class::ENCODING)
end
end
class UniversalString < RASN1::Types::OctetString
ID = 28
def self.type
'UniversalString'
end
private
def value_to_der
@value.to_s.dup.encode('UTF-32BE').b
end
def der_to_value(der, ber: false)
super
@value = der.dup.force_encoding('UTF-32BE')
end
end
end