gpgme-loongson 2.0.18

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,208 @@
1
+ module GPGME
2
+
3
+ ##
4
+ # A class whose purpose is to unify the way we work with the data (both input
5
+ # and output). Most of the calls expect instances of this class, or will try
6
+ # to create one from your parameters.
7
+ #
8
+ # Read the {#read}, {#write} and {#seek} methods for the most commonly used
9
+ # methods.
10
+ class Data
11
+
12
+ BLOCK_SIZE = 4096
13
+
14
+ class << self
15
+
16
+ ##
17
+ # We implement +self.new+ instead of initialize because objects are actually
18
+ # instantiated through the C API with stuff like +gpgme_data_new+.
19
+ #
20
+ # We try to create a {GPGME::Data} smartly depending on the object passed, and if
21
+ # another {GPGME::Data} object is passed, it just returns it, so when in
22
+ # doubt, you can always pass a {GPGME::Data} object.
23
+ #
24
+ # @example empty
25
+ # data = GPGME::Data.new
26
+ # data.write("stuff")
27
+ #
28
+ # @example from a string
29
+ # data = GPGME::Data.new("From a string")
30
+ #
31
+ # @example from a file
32
+ # data = GPGME::Data.new(File.open("secure.pass"))
33
+ #
34
+ # @example from a file descriptor
35
+ # data = GPGME::Data.new(0) # Standard input
36
+ # data = GPGME::Data.new(1) # Standard output
37
+ #
38
+ # file = File.open("secure.pass")
39
+ # data = GPGME::Data.new(file.fileno) # file descriptor
40
+ #
41
+ def new(object = nil)
42
+ if object.nil?
43
+ empty!
44
+ elsif object.is_a?(Data)
45
+ object
46
+ elsif object.is_a?(Integer)
47
+ from_fd(object)
48
+ elsif object.respond_to? :to_str
49
+ from_str(object.to_str)
50
+ elsif object.respond_to? :to_io
51
+ from_io(object.to_io)
52
+ elsif object.respond_to? :open
53
+ from_io(object.open)
54
+ elsif defined?(StringIO) and object.is_a?(StringIO)
55
+ from_io(object)
56
+ end
57
+ end
58
+
59
+ # Create a new instance with an empty buffer.
60
+ def empty!
61
+ rdh = []
62
+ err = GPGME::gpgme_data_new(rdh)
63
+ exc = GPGME::error_to_exception(err)
64
+ raise exc if exc
65
+ rdh.first
66
+ end
67
+
68
+ # Create a new instance with internal buffer.
69
+ def from_str(string)
70
+ rdh = []
71
+ err = GPGME::gpgme_data_new_from_mem(rdh, string, string.bytesize)
72
+ exc = GPGME::error_to_exception(err)
73
+ raise exc if exc
74
+ rdh.first
75
+ end
76
+
77
+ # Create a new instance associated with a given IO.
78
+ def from_io(io)
79
+ from_callbacks(IOCallbacks.new(io))
80
+ end
81
+
82
+ # Create a new instance from the specified file descriptor.
83
+ def from_fd(fd)
84
+ rdh = []
85
+ err = GPGME::gpgme_data_new_from_fd(rdh, fd)
86
+ exc = GPGME::error_to_exception(err)
87
+ raise exc if exc
88
+ rdh.first
89
+ end
90
+
91
+ # Create a new instance from the specified callbacks.
92
+ def from_callbacks(callbacks, hook_value = nil)
93
+ rdh = []
94
+ err = GPGME::gpgme_data_new_from_cbs(rdh, callbacks, hook_value)
95
+ exc = GPGME::error_to_exception(err)
96
+ raise exc if exc
97
+ rdh.first
98
+ end
99
+ end # class << self
100
+
101
+ # Read at most +length+ bytes from the data object, or to the end
102
+ # of file if +length+ is omitted or is +nil+.
103
+ #
104
+ # @example
105
+ # data = GPGME::Data.new("From a string")
106
+ # data.read # => "From a string"
107
+ #
108
+ # @example
109
+ # data = GPGME::Data.new("From a string")
110
+ # data.read(4) # => "From"
111
+ #
112
+ def read(length = nil)
113
+ if length
114
+ GPGME::gpgme_data_read(self, length)
115
+ else
116
+ buf = String.new
117
+ loop do
118
+ s = GPGME::gpgme_data_read(self, BLOCK_SIZE)
119
+ break unless s
120
+ buf << s
121
+ end
122
+ buf
123
+ end
124
+ end
125
+
126
+ ##
127
+ # Seek to a given +offset+ in the data object according to the
128
+ # value of +whence+.
129
+ #
130
+ # @example going to the beginning of the buffer after writing something
131
+ # data = GPGME::Data.new("Some data")
132
+ # data.read # => "Some data"
133
+ # data.read # => ""
134
+ # data.seek 0
135
+ # data.read # => "Some data"
136
+ #
137
+ def seek(offset, whence = IO::SEEK_SET)
138
+ GPGME::gpgme_data_seek(self, offset, IO::SEEK_SET)
139
+ end
140
+
141
+ ##
142
+ # Writes +length+ bytes from +buffer+ into the data object.
143
+ # Writes the full buffer if no length passed.
144
+ #
145
+ # @example
146
+ # data = GPGME::Data.new
147
+ # data.write "hola"
148
+ # data.seek 0
149
+ # data.read # => "hola"
150
+ #
151
+ # @example
152
+ # data = GPGME::Data.new
153
+ # data.write "hola", 2
154
+ # data.seek 0
155
+ # data.read # => "ho"
156
+ #
157
+ def write(buffer, length = buffer.length)
158
+ GPGME::gpgme_data_write(self, buffer, length)
159
+ end
160
+
161
+ ##
162
+ # Return the encoding of the underlying data.
163
+ def encoding
164
+ GPGME::gpgme_data_get_encoding(self)
165
+ end
166
+
167
+ ##
168
+ # Sets the encoding for this buffer. Accepts only values in one of the
169
+ # DATA_ENCODING_* constants.
170
+ #
171
+ # @raise [GPGME::Error::InvalidValue] if the value isn't accepted.
172
+ def encoding=(encoding)
173
+ err = GPGME::gpgme_data_set_encoding(self, encoding)
174
+ exc = GPGME::error_to_exception(err)
175
+ raise exc if exc
176
+ encoding
177
+ end
178
+
179
+ ##
180
+ # Return the file name of the underlying data.
181
+ def file_name
182
+ GPGME::gpgme_data_get_file_name(self)
183
+ end
184
+
185
+ ##
186
+ # Sets the file name for this buffer.
187
+ #
188
+ # @raise [GPGME::Error::InvalidValue] if the value isn't accepted.
189
+ def file_name=(file_name)
190
+ err = GPGME::gpgme_data_set_file_name(self, file_name)
191
+ exc = GPGME::error_to_exception(err)
192
+ raise exc if exc
193
+ file_name
194
+ end
195
+
196
+ ##
197
+ # Return the entire content of the data object as string.
198
+ def to_s
199
+ pos = seek(0, IO::SEEK_CUR)
200
+ begin
201
+ seek(0)
202
+ read
203
+ ensure
204
+ seek(pos)
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,87 @@
1
+ module GPGME
2
+
3
+ ##
4
+ # Convenience methods to check different aspects of the gpg system
5
+ # installation.
6
+ module Engine
7
+ class << self
8
+
9
+ ##
10
+ # Verify that the engine implementing the protocol +proto+ is installed in
11
+ # the system. Can be one of +PROTOCOL_OpenPGP+ or +PROTOCOL_CMS+.
12
+ #
13
+ # @return [Boolean] true if the engine is installed.
14
+ #
15
+ # @example
16
+ # GPGME::Engine.check_version(GPGME::PROTOCOL_OpenPGP) # => true
17
+ #
18
+ def check_version(proto)
19
+ err = GPGME::gpgme_engine_check_version(proto)
20
+ exc = GPGME::error_to_exception(err)
21
+ !exc
22
+ end
23
+
24
+ ##
25
+ # Return an array of {GPGME::EngineInfo} structures of enabled engines.
26
+ #
27
+ # @example
28
+ # GPGME::Engine.info.first
29
+ # # => #<GPGME::EngineInfo:0x00000100d4fbd8
30
+ # @file_name="/usr/local/bin/gpg",
31
+ # @protocol=0,
32
+ # @req_version="1.3.0",
33
+ # @version="1.4.11">
34
+ #
35
+ def info
36
+ rinfo = []
37
+ GPGME::gpgme_get_engine_info(rinfo)
38
+ rinfo
39
+ end
40
+
41
+ ##
42
+ # Change the default configuration of the crypto engine implementing
43
+ # protocol +proto+.
44
+ #
45
+ # @param proto
46
+ # Can be one of +PROTOCOL_OpenPGP+ or +PROTOCOL_CMS+.
47
+ #
48
+ # @param file_name
49
+ # The file name of the executable program implementing the protocol.
50
+ #
51
+ # @param home_dir
52
+ # The directory name of the configuration directory.
53
+ #
54
+ # @example
55
+ # GPGME::Engine.set
56
+ #
57
+ def set_info(proto, file_name, home_dir)
58
+ err = GPGME::gpgme_set_engine_info(proto, file_name, home_dir)
59
+ exc = GPGME::error_to_exception(err)
60
+ raise exc if exc
61
+ end
62
+
63
+ ##
64
+ # Sets the home dir for the configuration options. This way one could,
65
+ # for example, load the keys from a customized keychain.
66
+ #
67
+ # @example
68
+ # GPGME::Engine.home_dir = '/tmp'
69
+ #
70
+ def home_dir=(home_dir)
71
+ current = info.first
72
+ set_info current.protocol, current.file_name, home_dir
73
+ end
74
+
75
+ ##
76
+ # Return the default configuration.
77
+ #
78
+ # @example
79
+ # GPGME::Engine.dirinfo('homedir')
80
+ # # => '/home/user/.gnupg"
81
+ #
82
+ def dirinfo(what)
83
+ GPGME::gpgme_get_dirinfo(what)
84
+ end
85
+ end # class << self
86
+ end # class Engine
87
+ end # module GPGME
@@ -0,0 +1,66 @@
1
+ module GPGME
2
+ class Error < StandardError
3
+ def initialize(error)
4
+ @error = error
5
+ end
6
+ attr_reader :error
7
+
8
+ # Return the error code.
9
+ #
10
+ # The error code indicates the type of an error, or the reason why
11
+ # an operation failed.
12
+ def code
13
+ GPGME::gpgme_err_code(@error)
14
+ end
15
+
16
+ # Return the error source.
17
+ #
18
+ # The error source has not a precisely defined meaning. Sometimes
19
+ # it is the place where the error happened, sometimes it is the
20
+ # place where an error was encoded into an error value. Usually
21
+ # the error source will give an indication to where to look for
22
+ # the problem. This is not always true, but it is attempted to
23
+ # achieve this goal.
24
+ def source
25
+ GPGME::gpgme_err_source(@error)
26
+ end
27
+
28
+ # Return a description of the error code.
29
+ def message
30
+ GPGME::gpgme_strerror(@error)
31
+ end
32
+
33
+ class General < self; end
34
+ class InvalidValue < self; end
35
+ class UnusablePublicKey < self
36
+ attr_accessor :keys
37
+ end
38
+ class UnusableSecretKey < self
39
+ attr_accessor :keys
40
+ end
41
+ class NoData < self; end
42
+ class Conflict < self; end
43
+ class NotImplemented < self; end
44
+ class DecryptFailed < self; end
45
+ class BadPassphrase < self; end
46
+ class Canceled < self; end
47
+ class InvalidEngine < self; end
48
+ class AmbiguousName < self; end
49
+ class WrongKeyUsage < self
50
+ attr_accessor :key_usage
51
+ end
52
+ class CertificateRevoked < self; end
53
+ class CertificateExpired < self; end
54
+ class NoCRLKnown < self; end
55
+ class NoPolicyMatch < self; end
56
+ class NoSecretKey < self; end
57
+ class MissingCertificate < self; end
58
+ class BadCertificateChain < self; end
59
+ class UnsupportedAlgorithm < self
60
+ attr_accessor :algorithm
61
+ end
62
+ class BadSignature < self; end
63
+ class NoPublicKey < self; end
64
+ class InvalidVersion < self; end
65
+ end
66
+ end
@@ -0,0 +1,21 @@
1
+ module GPGME
2
+ class IOCallbacks
3
+ def initialize(io)
4
+ @io = io
5
+ end
6
+
7
+ def read(hook, length)
8
+ @io.read(length)
9
+ end
10
+
11
+ def write(hook, buffer, length)
12
+ @io.write(buffer[0 .. length])
13
+ end
14
+
15
+ def seek(hook, offset, whence)
16
+ return @io.pos if offset == 0 && whence == IO::SEEK_CUR
17
+ @io.seek(offset, whence)
18
+ @io.pos
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,248 @@
1
+ module GPGME
2
+
3
+ ##
4
+ # A ruby representation of a public or a secret key.
5
+ #
6
+ # Every key has two instances of {GPGME::SubKey}, accessible through
7
+ # {.subkeys}, and with a {.primary_subkey} where most attributes are
8
+ # derived from, like the +fingerprint+.
9
+ #
10
+ # Also, every key has at least a {GPGME::UserID}, accessible through
11
+ # {.uids}, with a {.primary_uid}, where other attributes are derived from,
12
+ # like +email+ or +name+
13
+ class Key
14
+ private_class_method :new
15
+
16
+ attr_reader :keylist_mode, :protocol, :owner_trust
17
+ attr_reader :issuer_serial, :issuer_name, :chain_id
18
+ attr_reader :subkeys, :uids
19
+
20
+ include KeyCommon
21
+
22
+ class << self
23
+
24
+ ##
25
+ # Returns an array of {GPGME::Key} objects that match the parameters.
26
+ # * +secret+ set to +:secret+ to get only secret keys, or to +:public+ to
27
+ # get only public keys.
28
+ # * +keys_or_names+ an array or an item that can be either {GPGME::Key}
29
+ # elements, or string identifiers like the email or the sha. Leave
30
+ # blank to get all.
31
+ # * +purposes+ get only keys that are usable for any of these purposes.
32
+ # See {GPGME::Key} for a list of possible key capabilities.
33
+ #
34
+ # @example
35
+ # GPGME::Key.find :secret # => first secret key found
36
+ #
37
+ # @example
38
+ # GPGME::Key.find(:public, "mrsimo@example.com")
39
+ # # => return only public keys that match mrsimo@example.com
40
+ #
41
+ # @example
42
+ # GPGME::Key.find(:public, "mrsimo@example.com", :sign)
43
+ # # => return the public keys that match mrsimo@example.com and are
44
+ # # capable of signing
45
+ def find(secret, keys_or_names = nil, purposes = [])
46
+ secret = (secret == :secret)
47
+ keys_or_names = [""] if keys_or_names.nil? || (keys_or_names.is_a?(Array) && keys_or_names.empty?)
48
+ keys_or_names = [keys_or_names].flatten
49
+ purposes = [purposes].flatten.compact.uniq
50
+
51
+ keys = []
52
+ keys_or_names.each do |key_or_name|
53
+ case key_or_name
54
+ when Key then keys << key_or_name
55
+ when String
56
+ GPGME::Ctx.new do |ctx|
57
+ keys += ctx.keys(key_or_name, secret).select do |k|
58
+ k.usable_for?(purposes)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ keys
64
+ end
65
+
66
+ def get(fingerprint)
67
+ Ctx.new do |ctx|
68
+ ctx.get_key(fingerprint)
69
+ end
70
+ end
71
+
72
+ # Exports public keys
73
+ #
74
+ # GPGME::Key.export pattern, options
75
+ #
76
+ # Private keys cannot be exported due to GPGME restrictions.
77
+ #
78
+ # @param pattern
79
+ # Identifier of the key to export.
80
+ #
81
+ # @param [Hash] options
82
+ # * +:output+ specify where to write the key to. It will be converted to
83
+ # a {GPGME::Data}, so it could be a file, for example.
84
+ # * Any other option accepted by {GPGME::Ctx.new}
85
+ #
86
+ # @return [GPGME::Data] the exported key.
87
+ #
88
+ # @example
89
+ # key = GPGME::Key.export "mrsimo@example.com"
90
+ #
91
+ # @example writing to a file
92
+ # out = File.open("my.key", "w+")
93
+ # GPGME::Key.export "mrsimo@example.com", :output => out
94
+ #
95
+ def export(pattern, options = {})
96
+ output = Data.new(options[:output])
97
+
98
+ GPGME::Ctx.new(options) do |ctx|
99
+ ctx.export_keys(pattern, output)
100
+ end
101
+
102
+ output.seek(0)
103
+ output
104
+ end
105
+
106
+ # Imports a key
107
+ #
108
+ # GPGME::Key.import keydata, options
109
+ #
110
+ # @param keydata
111
+ # The key to import. It will be converted to a {GPGME::Data} object,
112
+ # so could be a file, for example.
113
+ # @param options
114
+ # Any other option accepted by {GPGME::Ctx.new}
115
+ #
116
+ # @example
117
+ # GPGME::Key.import(File.open("my.key"))
118
+ #
119
+ def import(keydata, options = {})
120
+ GPGME::Ctx.new(options) do |ctx|
121
+ ctx.import_keys(Data.new(keydata))
122
+ ctx.import_result
123
+ end
124
+ end
125
+ end
126
+
127
+ ##
128
+ # Exports this key. Accepts the same options as {GPGME::Ctx.new}, and
129
+ # +options[:output]+, where you can specify something that can become a
130
+ # {GPGME::Data}, where the output will go.
131
+ #
132
+ # @example
133
+ # key.export(:armor => true)
134
+ # # => GPGME::Data you can read with ASCII armored format
135
+ #
136
+ # @example
137
+ # file = File.open("key.asc", "w+")
138
+ # key.export(:output => file)
139
+ # # => the key will be written to the file.
140
+ #
141
+ def export(options = {})
142
+ Key.export self.sha, options
143
+ end
144
+
145
+ ##
146
+ # Delete this key. If it's public, and has a secret one it will fail unless
147
+ # +allow_secret+ is specified as true.
148
+ def delete!(allow_secret = false)
149
+ GPGME::Ctx.new do |ctx|
150
+ ctx.delete_key self, allow_secret
151
+ end
152
+ end
153
+
154
+ ##
155
+ # Returns true if the key has an expiry date else false
156
+ def expires?
157
+ primary_subkey.expires?
158
+ end
159
+
160
+ ##
161
+ # Returns the expiry date for this key
162
+ def expires
163
+ primary_subkey.expires
164
+ end
165
+
166
+ ##
167
+ # Returns true if the key is expired
168
+ def expired
169
+ subkeys.any?(&:expired)
170
+ end
171
+
172
+ def primary_subkey
173
+ @primary_subkey ||= subkeys.first
174
+ end
175
+
176
+ ##
177
+ # Short descriptive value. Can be used to identify the key.
178
+ def sha
179
+ primary_subkey.sha
180
+ end
181
+
182
+ ##
183
+ # Longer descriptive value. Can be used to identify the key.
184
+ def fingerprint
185
+ primary_subkey.fingerprint
186
+ end
187
+
188
+ ##
189
+ # Returns the main {GPGME::UserID} for this key.
190
+ def primary_uid
191
+ uids.first
192
+ end
193
+
194
+ ##
195
+ # Returns the email for this key.
196
+ def email
197
+ primary_uid.email
198
+ end
199
+
200
+ ##
201
+ # Returns the issuer name for this key.
202
+ def name
203
+ primary_uid.name
204
+ end
205
+
206
+ ##
207
+ # Returns the issuer comment for this key.
208
+ def comment
209
+ primary_uid.comment
210
+ end
211
+
212
+ def ==(another_key)
213
+ self.class === another_key and fingerprint == another_key.fingerprint
214
+ end
215
+
216
+ def inspect
217
+ sprintf("#<#{self.class} %s %4d%s/%s %s trust=%s, owner_trust=%s, \
218
+ capability=%s, subkeys=%s, uids=%s>",
219
+ primary_subkey.secret? ? 'sec' : 'pub',
220
+ primary_subkey.length,
221
+ primary_subkey.pubkey_algo_letter,
222
+ primary_subkey.fingerprint[-8 .. -1],
223
+ primary_subkey.timestamp.strftime('%Y-%m-%d'),
224
+ trust.inspect,
225
+ VALIDITY_NAMES[@owner_trust].inspect,
226
+ capability.inspect,
227
+ subkeys.inspect,
228
+ uids.inspect)
229
+ end
230
+
231
+ def to_s
232
+ primary_subkey = subkeys[0]
233
+ s = sprintf("%s %4d%s/%s %s\n",
234
+ primary_subkey.secret? ? 'sec' : 'pub',
235
+ primary_subkey.length,
236
+ primary_subkey.pubkey_algo_letter,
237
+ primary_subkey.fingerprint[-8 .. -1],
238
+ primary_subkey.timestamp.strftime('%Y-%m-%d'))
239
+ uids.each do |user_id|
240
+ s << "uid\t\t#{user_id.name} <#{user_id.email}>\n"
241
+ end
242
+ subkeys.each do |subkey|
243
+ s << subkey.to_s
244
+ end
245
+ s
246
+ end
247
+ end
248
+ end