Add glide.yaml and vendor deps
This commit is contained in:
parent
db918f12ad
commit
5b3d5e81bd
18880 changed files with 5166045 additions and 1 deletions
1
vendor/github.com/mtrmac/gpgme/.gitignore
generated
vendored
Normal file
1
vendor/github.com/mtrmac/gpgme/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
testdata/gpghome/random_seed
|
||||
12
vendor/github.com/mtrmac/gpgme/LICENSE
generated
vendored
Normal file
12
vendor/github.com/mtrmac/gpgme/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Copyright (c) 2015, James Fargher <proglottis@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
13
vendor/github.com/mtrmac/gpgme/README.md
generated
vendored
Normal file
13
vendor/github.com/mtrmac/gpgme/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# GPGME (golang)
|
||||
|
||||
Go wrapper for the GPGME library.
|
||||
|
||||
This library is intended for use with desktop applications. If you are looking to add OpenPGP support to a server application I suggest you first look at [golang.org/x/crypto/openpgp](https://godoc.org/golang.org/x/crypto/openpgp).
|
||||
|
||||
## Installation
|
||||
|
||||
go get -u github.com/proglottis/gpgme
|
||||
|
||||
## Documentation
|
||||
|
||||
* [godoc](https://godoc.org/github.com/proglottis/gpgme)
|
||||
42
vendor/github.com/mtrmac/gpgme/callbacks.go
generated
vendored
Normal file
42
vendor/github.com/mtrmac/gpgme/callbacks.go
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package gpgme
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var callbacks struct {
|
||||
sync.Mutex
|
||||
m map[uintptr]interface{}
|
||||
c uintptr
|
||||
}
|
||||
|
||||
func callbackAdd(v interface{}) uintptr {
|
||||
callbacks.Lock()
|
||||
defer callbacks.Unlock()
|
||||
if callbacks.m == nil {
|
||||
callbacks.m = make(map[uintptr]interface{})
|
||||
}
|
||||
callbacks.c++
|
||||
ret := callbacks.c
|
||||
callbacks.m[ret] = v
|
||||
return ret
|
||||
}
|
||||
|
||||
func callbackLookup(c uintptr) interface{} {
|
||||
callbacks.Lock()
|
||||
defer callbacks.Unlock()
|
||||
ret := callbacks.m[c]
|
||||
if ret == nil {
|
||||
panic("callback pointer not found")
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func callbackDelete(c uintptr) {
|
||||
callbacks.Lock()
|
||||
defer callbacks.Unlock()
|
||||
if callbacks.m[c] == nil {
|
||||
panic("callback pointer not found")
|
||||
}
|
||||
delete(callbacks.m, c)
|
||||
}
|
||||
191
vendor/github.com/mtrmac/gpgme/data.go
generated
vendored
Normal file
191
vendor/github.com/mtrmac/gpgme/data.go
generated
vendored
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
package gpgme
|
||||
|
||||
// #include <string.h>
|
||||
// #include <gpgme.h>
|
||||
// #include <errno.h>
|
||||
// #include "go_gpgme.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
SeekSet = C.SEEK_SET
|
||||
SeekCur = C.SEEK_CUR
|
||||
SeekEnd = C.SEEK_END
|
||||
)
|
||||
|
||||
//export gogpgme_readfunc
|
||||
func gogpgme_readfunc(handle, buffer unsafe.Pointer, size C.size_t) C.ssize_t {
|
||||
d := callbackLookup(uintptr(handle)).(*Data)
|
||||
if len(d.buf) < int(size) {
|
||||
d.buf = make([]byte, size)
|
||||
}
|
||||
n, err := d.r.Read(d.buf[:size])
|
||||
if err != nil && err != io.EOF {
|
||||
C.gpgme_err_set_errno(C.EIO)
|
||||
return -1
|
||||
}
|
||||
C.memcpy(buffer, unsafe.Pointer(&d.buf[0]), C.size_t(n))
|
||||
return C.ssize_t(n)
|
||||
}
|
||||
|
||||
//export gogpgme_writefunc
|
||||
func gogpgme_writefunc(handle, buffer unsafe.Pointer, size C.size_t) C.ssize_t {
|
||||
d := callbackLookup(uintptr(handle)).(*Data)
|
||||
if len(d.buf) < int(size) {
|
||||
d.buf = make([]byte, size)
|
||||
}
|
||||
C.memcpy(unsafe.Pointer(&d.buf[0]), buffer, C.size_t(size))
|
||||
n, err := d.w.Write(d.buf[:size])
|
||||
if err != nil && err != io.EOF {
|
||||
C.gpgme_err_set_errno(C.EIO)
|
||||
return -1
|
||||
}
|
||||
return C.ssize_t(n)
|
||||
}
|
||||
|
||||
//export gogpgme_seekfunc
|
||||
func gogpgme_seekfunc(handle unsafe.Pointer, offset C.off_t, whence C.int) C.off_t {
|
||||
d := callbackLookup(uintptr(handle)).(*Data)
|
||||
n, err := d.s.Seek(int64(offset), int(whence))
|
||||
if err != nil {
|
||||
C.gpgme_err_set_errno(C.EIO)
|
||||
return -1
|
||||
}
|
||||
return C.off_t(n)
|
||||
}
|
||||
|
||||
// The Data buffer used to communicate with GPGME
|
||||
type Data struct {
|
||||
dh C.gpgme_data_t
|
||||
buf []byte
|
||||
cbs C.struct_gpgme_data_cbs
|
||||
r io.Reader
|
||||
w io.Writer
|
||||
s io.Seeker
|
||||
cbc uintptr
|
||||
}
|
||||
|
||||
func newData() *Data {
|
||||
d := &Data{}
|
||||
runtime.SetFinalizer(d, (*Data).Close)
|
||||
return d
|
||||
}
|
||||
|
||||
// NewData returns a new memory based data buffer
|
||||
func NewData() (*Data, error) {
|
||||
d := newData()
|
||||
return d, handleError(C.gpgme_data_new(&d.dh))
|
||||
}
|
||||
|
||||
// NewDataFile returns a new file based data buffer
|
||||
func NewDataFile(f *os.File) (*Data, error) {
|
||||
d := newData()
|
||||
return d, handleError(C.gpgme_data_new_from_fd(&d.dh, C.int(f.Fd())))
|
||||
}
|
||||
|
||||
// NewDataBytes returns a new memory based data buffer that contains `b` bytes
|
||||
func NewDataBytes(b []byte) (*Data, error) {
|
||||
d := newData()
|
||||
var cb *C.char
|
||||
if len(b) != 0 {
|
||||
cb = (*C.char)(unsafe.Pointer(&b[0]))
|
||||
}
|
||||
return d, handleError(C.gpgme_data_new_from_mem(&d.dh, cb, C.size_t(len(b)), 1))
|
||||
}
|
||||
|
||||
// NewDataReader returns a new callback based data buffer
|
||||
func NewDataReader(r io.Reader) (*Data, error) {
|
||||
d := newData()
|
||||
d.r = r
|
||||
d.cbs.read = C.gpgme_data_read_cb_t(C.gogpgme_readfunc)
|
||||
cbc := callbackAdd(d)
|
||||
d.cbc = cbc
|
||||
return d, handleError(C.gogpgme_data_new_from_cbs(&d.dh, &d.cbs, C.uintptr_t(cbc)))
|
||||
}
|
||||
|
||||
// NewDataWriter returns a new callback based data buffer
|
||||
func NewDataWriter(w io.Writer) (*Data, error) {
|
||||
d := newData()
|
||||
d.w = w
|
||||
d.cbs.write = C.gpgme_data_write_cb_t(C.gogpgme_writefunc)
|
||||
cbc := callbackAdd(d)
|
||||
d.cbc = cbc
|
||||
return d, handleError(C.gogpgme_data_new_from_cbs(&d.dh, &d.cbs, C.uintptr_t(cbc)))
|
||||
}
|
||||
|
||||
// NewDataReadWriter returns a new callback based data buffer
|
||||
func NewDataReadWriter(rw io.ReadWriter) (*Data, error) {
|
||||
d := newData()
|
||||
d.r = rw
|
||||
d.w = rw
|
||||
d.cbs.read = C.gpgme_data_read_cb_t(C.gogpgme_readfunc)
|
||||
d.cbs.write = C.gpgme_data_write_cb_t(C.gogpgme_writefunc)
|
||||
cbc := callbackAdd(d)
|
||||
d.cbc = cbc
|
||||
return d, handleError(C.gogpgme_data_new_from_cbs(&d.dh, &d.cbs, C.uintptr_t(cbc)))
|
||||
}
|
||||
|
||||
// NewDataReadWriteSeeker returns a new callback based data buffer
|
||||
func NewDataReadWriteSeeker(rw io.ReadWriteSeeker) (*Data, error) {
|
||||
d := newData()
|
||||
d.r = rw
|
||||
d.w = rw
|
||||
d.s = rw
|
||||
d.cbs.read = C.gpgme_data_read_cb_t(C.gogpgme_readfunc)
|
||||
d.cbs.write = C.gpgme_data_write_cb_t(C.gogpgme_writefunc)
|
||||
d.cbs.seek = C.gpgme_data_seek_cb_t(C.gogpgme_seekfunc)
|
||||
cbc := callbackAdd(d)
|
||||
d.cbc = cbc
|
||||
return d, handleError(C.gogpgme_data_new_from_cbs(&d.dh, &d.cbs, C.uintptr_t(cbc)))
|
||||
}
|
||||
|
||||
// Close releases any resources associated with the data buffer
|
||||
func (d *Data) Close() error {
|
||||
if d.dh == nil {
|
||||
return nil
|
||||
}
|
||||
if d.cbc > 0 {
|
||||
callbackDelete(d.cbc)
|
||||
}
|
||||
_, err := C.gpgme_data_release(d.dh)
|
||||
d.dh = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Data) Write(p []byte) (int, error) {
|
||||
n, err := C.gpgme_data_write(d.dh, unsafe.Pointer(&p[0]), C.size_t(len(p)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
func (d *Data) Read(p []byte) (int, error) {
|
||||
n, err := C.gpgme_data_read(d.dh, unsafe.Pointer(&p[0]), C.size_t(len(p)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return int(n), nil
|
||||
}
|
||||
|
||||
func (d *Data) Seek(offset int64, whence int) (int64, error) {
|
||||
n, err := C.gpgme_data_seek(d.dh, C.off_t(offset), C.int(whence))
|
||||
return int64(n), err
|
||||
}
|
||||
|
||||
// Name returns the associated filename if any
|
||||
func (d *Data) Name() string {
|
||||
return C.GoString(C.gpgme_data_get_file_name(d.dh))
|
||||
}
|
||||
92
vendor/github.com/mtrmac/gpgme/data_test.go
generated
vendored
Normal file
92
vendor/github.com/mtrmac/gpgme/data_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package gpgme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewData(t *testing.T) {
|
||||
dh, err := NewData()
|
||||
checkError(t, err)
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err := dh.Write([]byte(testData))
|
||||
checkError(t, err)
|
||||
}
|
||||
_, err = dh.Seek(0, SeekSet)
|
||||
checkError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, dh)
|
||||
checkError(t, err)
|
||||
expected := bytes.Repeat([]byte(testData), 5)
|
||||
diff(t, buf.Bytes(), expected)
|
||||
|
||||
dh.Close()
|
||||
}
|
||||
|
||||
func TestNewDataBytes(t *testing.T) {
|
||||
// Test ordinary data, and empty slices
|
||||
for _, content := range [][]byte{[]byte("content"), []byte{}} {
|
||||
dh, err := NewDataBytes(content)
|
||||
checkError(t, err)
|
||||
|
||||
_, err = dh.Seek(0, SeekSet)
|
||||
checkError(t, err)
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, dh)
|
||||
checkError(t, err)
|
||||
diff(t, buf.Bytes(), content)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDataNewDataFile(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "gpgme")
|
||||
checkError(t, err)
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
}()
|
||||
dh, err := NewDataFile(f)
|
||||
checkError(t, err)
|
||||
defer dh.Close()
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err := dh.Write([]byte(testData))
|
||||
checkError(t, err)
|
||||
}
|
||||
_, err = dh.Seek(0, SeekSet)
|
||||
checkError(t, err)
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, dh)
|
||||
checkError(t, err)
|
||||
expected := bytes.Repeat([]byte(testData), 5)
|
||||
diff(t, buf.Bytes(), expected)
|
||||
}
|
||||
|
||||
func TestDataNewDataReader(t *testing.T) {
|
||||
r := bytes.NewReader([]byte(testData))
|
||||
dh, err := NewDataReader(r)
|
||||
checkError(t, err)
|
||||
var buf bytes.Buffer
|
||||
_, err = io.Copy(&buf, dh)
|
||||
checkError(t, err)
|
||||
diff(t, buf.Bytes(), []byte(testData))
|
||||
|
||||
dh.Close()
|
||||
}
|
||||
|
||||
func TestDataNewDataWriter(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
dh, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err := dh.Write([]byte(testData))
|
||||
checkError(t, err)
|
||||
}
|
||||
expected := bytes.Repeat([]byte(testData), 5)
|
||||
diff(t, buf.Bytes(), expected)
|
||||
|
||||
dh.Close()
|
||||
}
|
||||
19
vendor/github.com/mtrmac/gpgme/examples/decrypt.go
generated
vendored
Normal file
19
vendor/github.com/mtrmac/gpgme/examples/decrypt.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/proglottis/gpgme"
|
||||
)
|
||||
|
||||
func main() {
|
||||
plain, err := gpgme.Decrypt(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer plain.Close()
|
||||
if _, err := io.Copy(os.Stdout, plain); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
39
vendor/github.com/mtrmac/gpgme/examples/encrypt.go
generated
vendored
Normal file
39
vendor/github.com/mtrmac/gpgme/examples/encrypt.go
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"github.com/proglottis/gpgme"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
filter := flag.Arg(0)
|
||||
if filter == "" {
|
||||
panic("must specify recipient filter")
|
||||
}
|
||||
recipients, err := gpgme.FindKeys(filter, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(recipients) < 1 {
|
||||
panic("no keys match")
|
||||
}
|
||||
plain, err := gpgme.NewDataReader(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cipher, err := gpgme.NewDataWriter(os.Stdout)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx, err := gpgme.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx.SetArmor(true)
|
||||
if err := ctx.Encrypt(recipients, 0, plain, cipher); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
89
vendor/github.com/mtrmac/gpgme/go_gpgme.c
generated
vendored
Normal file
89
vendor/github.com/mtrmac/gpgme/go_gpgme.c
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#include "go_gpgme.h"
|
||||
|
||||
gpgme_error_t gogpgme_data_new_from_cbs(gpgme_data_t *dh, gpgme_data_cbs_t cbs, uintptr_t handle) {
|
||||
return gpgme_data_new_from_cbs(dh, cbs, (void *)handle);
|
||||
}
|
||||
|
||||
void gogpgme_set_passphrase_cb(gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb, uintptr_t handle) {
|
||||
gpgme_set_passphrase_cb(ctx, cb, (void *)handle);
|
||||
}
|
||||
|
||||
unsigned int key_revoked(gpgme_key_t k) {
|
||||
return k->revoked;
|
||||
}
|
||||
|
||||
unsigned int key_expired(gpgme_key_t k) {
|
||||
return k->expired;
|
||||
}
|
||||
|
||||
unsigned int key_disabled(gpgme_key_t k) {
|
||||
return k->disabled;
|
||||
}
|
||||
|
||||
unsigned int key_invalid(gpgme_key_t k) {
|
||||
return k->invalid;
|
||||
}
|
||||
|
||||
unsigned int key_can_encrypt(gpgme_key_t k) {
|
||||
return k->can_encrypt;
|
||||
}
|
||||
|
||||
unsigned int key_can_sign(gpgme_key_t k) {
|
||||
return k->can_sign;
|
||||
}
|
||||
|
||||
unsigned int key_can_certify(gpgme_key_t k) {
|
||||
return k->can_certify;
|
||||
}
|
||||
|
||||
unsigned int key_secret(gpgme_key_t k) {
|
||||
return k->secret;
|
||||
}
|
||||
|
||||
unsigned int key_can_authenticate(gpgme_key_t k) {
|
||||
return k->can_authenticate;
|
||||
}
|
||||
|
||||
unsigned int key_is_qualified(gpgme_key_t k) {
|
||||
return k->is_qualified;
|
||||
}
|
||||
|
||||
unsigned int signature_wrong_key_usage(gpgme_signature_t s) {
|
||||
return s->wrong_key_usage;
|
||||
}
|
||||
|
||||
unsigned int signature_pka_trust(gpgme_signature_t s) {
|
||||
return s->pka_trust;
|
||||
}
|
||||
|
||||
unsigned int signature_chain_model(gpgme_signature_t s) {
|
||||
return s->chain_model;
|
||||
}
|
||||
|
||||
unsigned int subkey_revoked(gpgme_subkey_t k) {
|
||||
return k->revoked;
|
||||
}
|
||||
|
||||
unsigned int subkey_expired(gpgme_subkey_t k) {
|
||||
return k->expired;
|
||||
}
|
||||
|
||||
unsigned int subkey_disabled(gpgme_subkey_t k) {
|
||||
return k->disabled;
|
||||
}
|
||||
|
||||
unsigned int subkey_invalid(gpgme_subkey_t k) {
|
||||
return k->invalid;
|
||||
}
|
||||
|
||||
unsigned int subkey_secret(gpgme_subkey_t k) {
|
||||
return k->secret;
|
||||
}
|
||||
|
||||
unsigned int uid_revoked(gpgme_user_id_t u) {
|
||||
return u->revoked;
|
||||
}
|
||||
|
||||
unsigned int uid_invalid(gpgme_user_id_t u) {
|
||||
return u->invalid;
|
||||
}
|
||||
37
vendor/github.com/mtrmac/gpgme/go_gpgme.h
generated
vendored
Normal file
37
vendor/github.com/mtrmac/gpgme/go_gpgme.h
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef GO_GPGME_H
|
||||
#define GO_GPGME_H
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <stdint.h>
|
||||
|
||||
#include <gpgme.h>
|
||||
|
||||
extern ssize_t gogpgme_readfunc(void *handle, void *buffer, size_t size);
|
||||
extern ssize_t gogpgme_writefunc(void *handle, void *buffer, size_t size);
|
||||
extern off_t gogpgme_seekfunc(void *handle, off_t offset, int whence);
|
||||
extern gpgme_error_t gogpgme_passfunc(void *hook, char *uid_hint, char *passphrase_info, int prev_was_bad, int fd);
|
||||
extern gpgme_error_t gogpgme_data_new_from_cbs(gpgme_data_t *dh, gpgme_data_cbs_t cbs, uintptr_t handle);
|
||||
extern void gogpgme_set_passphrase_cb(gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb, uintptr_t handle);
|
||||
|
||||
extern unsigned int key_revoked(gpgme_key_t k);
|
||||
extern unsigned int key_expired(gpgme_key_t k);
|
||||
extern unsigned int key_disabled(gpgme_key_t k);
|
||||
extern unsigned int key_invalid(gpgme_key_t k);
|
||||
extern unsigned int key_can_encrypt(gpgme_key_t k);
|
||||
extern unsigned int key_can_sign(gpgme_key_t k);
|
||||
extern unsigned int key_can_certify(gpgme_key_t k);
|
||||
extern unsigned int key_secret(gpgme_key_t k);
|
||||
extern unsigned int key_can_authenticate(gpgme_key_t k);
|
||||
extern unsigned int key_is_qualified(gpgme_key_t k);
|
||||
extern unsigned int signature_wrong_key_usage(gpgme_signature_t s);
|
||||
extern unsigned int signature_pka_trust(gpgme_signature_t s);
|
||||
extern unsigned int signature_chain_model(gpgme_signature_t s);
|
||||
extern unsigned int subkey_revoked(gpgme_subkey_t k);
|
||||
extern unsigned int subkey_expired(gpgme_subkey_t k);
|
||||
extern unsigned int subkey_disabled(gpgme_subkey_t k);
|
||||
extern unsigned int subkey_invalid(gpgme_subkey_t k);
|
||||
extern unsigned int subkey_secret(gpgme_subkey_t k);
|
||||
extern unsigned int uid_revoked(gpgme_user_id_t u);
|
||||
extern unsigned int uid_invalid(gpgme_user_id_t u);
|
||||
|
||||
#endif
|
||||
740
vendor/github.com/mtrmac/gpgme/gpgme.go
generated
vendored
Normal file
740
vendor/github.com/mtrmac/gpgme/gpgme.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
399
vendor/github.com/mtrmac/gpgme/gpgme_test.go
generated
vendored
Normal file
399
vendor/github.com/mtrmac/gpgme/gpgme_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
package gpgme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testGPGHome = "./testdata/gpghome"
|
||||
testData = "data\n"
|
||||
testCipherText = `-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
hQEMAw4698hF4WUhAQf/SdkbF/zUE6YjBxscDurrUZunSnt87kipLXypSxTDIdgj
|
||||
O9huAaQwBz4uAJf2DuEN/7iAFGhi/v45NTujrG+7ocfjM3m/A2T80g4RVF5kKXBr
|
||||
pFFgH7bMRY6VdZt1GKI9izSO/uFkoKXG8M31tCX3hWntQUJ9p+n1avGpu3wo4Ru3
|
||||
CJhpL+ChDzXuZv4IK81ahrixEz4fJH0vd0TbsHpTXx4WPkTGXelM0R9PwiY7TovZ
|
||||
onGZUIplrfA1HUUbQfzExyFw3oAo1/almzD5CBIfq5EnU8Siy5BNulDXm0/44h8A
|
||||
lOUy6xqx7ITnWMYYf4a1cFoW80Yk+x6SYQqbcqHFQdJIAVr00V4pPV4ppFcXgdw/
|
||||
BxKERzDupyqS0tcfVFCYLRmvtQp7ceOS6jRW3geXPPIz1U/VYBvKlvFu4XTMCS6z
|
||||
4qY4SzZlFEsU
|
||||
=IQOA
|
||||
-----END PGP MESSAGE-----`
|
||||
textSignedCipherText = `-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
hQEMAw4698hF4WUhAQf9FaI8zSltIMcDxqGtpcTfcBtC30rcKqE/oa1bacxuZQKW
|
||||
uT671N7J2TjU8tLIsAO9lDSRHCsf6DbB+O6qOJsu6eJownyMUEmJ2oBON9Z2x+Ci
|
||||
aS0KeRqcRxNJYbIth9/ffa2I4sSBA0GS93yCfGKHNL4JvNo/dgVjJwOPWZ5TKu49
|
||||
n9h81LMwTQ8qpLGPeo7nsgBtSKNTi5s7pC0bd9HTii7gQcLUEeeqk5U7oG5CRN48
|
||||
zKPrVud8pIDvSoYuymZmjWI1MmF4xQ+6IHK7hWKMyA2RkS4CpyBPERMifc+y+K2+
|
||||
LnKLt2ul9jxgqv3fd/dU7UhyqdvJdj83tUvhN4Iru9LAuQHfVsP23keH8CHpUzCj
|
||||
PkuUYvpgmRdMSC+l3yBCqnaaAI51rRdyJ+HX4DrrinOFst2JfXEICiQAg5UkO4i/
|
||||
YYHsfD3xfk7MKMOY/DfV25OyAU6Yeq/5SMisONhtlzcosVU7HULudbIKSG6q/tCx
|
||||
jRGu+oMIBdiQ+eipnaLVetyGxSEDzxHH367NbxC9ffxK7I+Srmwh+oS/yMNuZA8r
|
||||
bUp6NbykK8Si7VNgVG1+yOIULLuR0VBO5+e2PKQU8FP0wABTn7h3zE8z4rCrcaZl
|
||||
43bc/TBUyTdWY79e2P1otaCbhQGAjfF8ClPbAdsFppykf5I2ZDDf8c67d0Nqui74
|
||||
Yry4/fF/2sAzyoyzdP6ktBw6pCA1MbwDqTGg7aEI8Es3X+jfh3qIaLnGmZ7jIyUl
|
||||
D4jgGAEpFU+mpPH8eukKuT+OJ3P6gdmSiAJH7+C96tlcEg9BNxjYNkCTil/3yygQ
|
||||
EV/5zFTEpzm4CtYHHdmY5uCaEJq/4hhE8BY8
|
||||
=8mxI
|
||||
-----END PGP MESSAGE-----`
|
||||
testSignedText = `-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
owEBQwG8/pANAwACAQMn/7Ain2E2AcsTYgBW47+PVGVzdCBtZXNzYWdlCokBHAQA
|
||||
AQIABgUCVuO/jwAKCRADJ/+wIp9hNh9lCACPiDkY0CqI9ss4EBcpToqnF/8NmV99
|
||||
2wi6FmbQnUmY98OMM2VJXrX6PvfD/X+FsiLog0CZU4heMEAI3Dd3qELgTfaTFqNc
|
||||
bbDkenzA0kO734WLsEU/z1F9iWAcfeF3crKqd3fBw5kZ1PkhuJFdcqQEOUQALvXY
|
||||
8VAtQmQWzf3sn2KIQ7R1wyAJVoUZaN5Xwc9Y0F1l4Xxifax8nkFBl35X6gmHRxZ7
|
||||
jlfmWMcAkXASNXl9/Yso2XGJMs85JPhZPJ3KJRuuurnhZSxAbDJMNBFJ+HbQv3y6
|
||||
pupeR7ut6pWJxr6MND793yoFGoRYwKklQdfP4xzFCatYRU4RkPBp95KJ
|
||||
=RMUj
|
||||
-----END PGP MESSAGE-----
|
||||
`
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
os.Setenv("GNUPGHOME", testGPGHome)
|
||||
unsetenvGPGAgentInfo()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func compareEngineInfo(t *testing.T, info *EngineInfo, proto Protocol, fileName, homeDir string) {
|
||||
for info != nil && info.Protocol() != proto {
|
||||
info = info.Next()
|
||||
}
|
||||
if info == nil {
|
||||
t.Errorf("Expected engine info %d not found", proto)
|
||||
return
|
||||
}
|
||||
if info.FileName() != fileName {
|
||||
t.Errorf("Testing file name %s does not match %s", info.FileName(), fileName)
|
||||
}
|
||||
if info.HomeDir() != homeDir {
|
||||
t.Errorf("Testing home directory %s does not match %s", info.HomeDir(), homeDir)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEngineInfo(t *testing.T) {
|
||||
testProto := ProtocolOpenPGP // Careful, this is global state!
|
||||
defer func() {
|
||||
SetEngineInfo(testProto, "", "") // Try to reset to defaults after we are done.
|
||||
}()
|
||||
|
||||
testFN := "testFN"
|
||||
testHomeDir := "testHomeDir"
|
||||
checkError(t, SetEngineInfo(testProto, testFN, testHomeDir))
|
||||
|
||||
info, err := GetEngineInfo()
|
||||
checkError(t, err)
|
||||
compareEngineInfo(t, info, testProto, testFN, testHomeDir)
|
||||
|
||||
// SetEngineInfo with empty strings works, using defaults which we don't know,
|
||||
// so just test that it doesn't fail.
|
||||
checkError(t, SetEngineInfo(testProto, testFN, ""))
|
||||
checkError(t, SetEngineInfo(testProto, "", testHomeDir))
|
||||
}
|
||||
|
||||
func ctxWithCallback(t *testing.T) *Context {
|
||||
skipGPG2x(t, "can only set password callback for GPG v1.x")
|
||||
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
checkError(t, ctx.SetCallback(func(uid_hint string, prev_was_bad bool, f *os.File) error {
|
||||
if prev_was_bad {
|
||||
t.Fatal("Bad passphrase")
|
||||
}
|
||||
_, err := io.WriteString(f, "password\n")
|
||||
return err
|
||||
}))
|
||||
return ctx
|
||||
}
|
||||
|
||||
func TestContext_Armor(t *testing.T) {
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
ctx.SetArmor(true)
|
||||
if !ctx.Armor() {
|
||||
t.Error("expected armor set")
|
||||
}
|
||||
ctx.SetArmor(false)
|
||||
if ctx.Armor() {
|
||||
t.Error("expected armor not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_TextMode(t *testing.T) {
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
ctx.SetTextMode(true)
|
||||
if !ctx.TextMode() {
|
||||
t.Error("expected textmode set")
|
||||
}
|
||||
ctx.SetTextMode(false)
|
||||
if ctx.TextMode() {
|
||||
t.Error("expected textmode not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_EngineInfo(t *testing.T) {
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
testProto := ProtocolOpenPGP
|
||||
testFN := "testFN"
|
||||
testHomeDir := "testHomeDir"
|
||||
checkError(t, ctx.SetEngineInfo(testProto, testFN, testHomeDir))
|
||||
|
||||
info := ctx.EngineInfo()
|
||||
compareEngineInfo(t, info, testProto, testFN, testHomeDir)
|
||||
|
||||
// SetEngineInfo with empty strings works, using defaults which we don't know,
|
||||
// so just test that it doesn't fail.
|
||||
checkError(t, ctx.SetEngineInfo(testProto, testFN, ""))
|
||||
checkError(t, ctx.SetEngineInfo(testProto, "", testHomeDir))
|
||||
}
|
||||
|
||||
func TestContext_Encrypt(t *testing.T) {
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
keys, err := FindKeys("test@example.com", true)
|
||||
checkError(t, err)
|
||||
|
||||
plain, err := NewDataBytes([]byte(testData))
|
||||
checkError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
cipher, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
|
||||
checkError(t, ctx.Encrypt(keys, 0, plain, cipher))
|
||||
if buf.Len() < 1 {
|
||||
t.Error("Expected encrypted bytes, got empty buffer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_Decrypt(t *testing.T) {
|
||||
ctx := ctxWithCallback(t)
|
||||
|
||||
cipher, err := NewDataBytes([]byte(testCipherText))
|
||||
checkError(t, err)
|
||||
var buf bytes.Buffer
|
||||
plain, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
checkError(t, ctx.Decrypt(cipher, plain))
|
||||
diff(t, buf.Bytes(), []byte("Test message\n"))
|
||||
}
|
||||
|
||||
func TestContext_DecryptVerify(t *testing.T) {
|
||||
ctx := ctxWithCallback(t)
|
||||
|
||||
cipher, err := NewDataBytes([]byte(textSignedCipherText))
|
||||
checkError(t, err)
|
||||
var buf bytes.Buffer
|
||||
plain, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
checkError(t, ctx.DecryptVerify(cipher, plain))
|
||||
diff(t, buf.Bytes(), []byte("Test message\n"))
|
||||
}
|
||||
|
||||
func TestContext_Sign(t *testing.T) {
|
||||
ctx := ctxWithCallback(t)
|
||||
|
||||
key, err := ctx.GetKey("test@example.com", true)
|
||||
checkError(t, err)
|
||||
|
||||
plain, err := NewDataBytes([]byte(testData))
|
||||
checkError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
signed, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
|
||||
checkError(t, ctx.Sign([]*Key{key}, plain, signed, SigModeNormal))
|
||||
if buf.Len() < 1 {
|
||||
t.Error("Expected signed bytes, got empty buffer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext_Verify(t *testing.T) {
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
|
||||
_, err = ctx.GetKey("test@example.com", false)
|
||||
checkError(t, err)
|
||||
|
||||
signed, err := NewDataBytes([]byte(testSignedText))
|
||||
checkError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
plain, err := NewDataWriter(&buf)
|
||||
checkError(t, err)
|
||||
|
||||
_, sigs, err := ctx.Verify(signed, nil, plain)
|
||||
checkError(t, err)
|
||||
|
||||
if len(sigs) != 1 {
|
||||
t.Error("Expected 1 signature")
|
||||
}
|
||||
sig := sigs[0]
|
||||
// Normalize
|
||||
expectedSig := Signature{
|
||||
Summary: SigSumValid | SigSumGreen,
|
||||
Fingerprint: "44B646DC347C31E867FF4F450327FFB0229F6136",
|
||||
Status: nil,
|
||||
Timestamp: sig.Timestamp, // Ignore in comparison
|
||||
ExpTimestamp: sig.ExpTimestamp, // Ignore in comparison
|
||||
WrongKeyUsage: false,
|
||||
PKATrust: 0,
|
||||
ChainModel: false,
|
||||
Validity: ValidityFull,
|
||||
ValidityReason: nil,
|
||||
PubkeyAlgo: sig.PubkeyAlgo, // Ignore in comparison
|
||||
HashAlgo: sig.HashAlgo, // Ignore in comparison
|
||||
}
|
||||
if sig != expectedSig {
|
||||
t.Errorf("Signature verification does not match: %#v vs. %#v", sig, expectedSig)
|
||||
}
|
||||
|
||||
diff(t, buf.Bytes(), []byte("Test message\n"))
|
||||
}
|
||||
|
||||
func TestContext_Import(t *testing.T) {
|
||||
homeDir, err := ioutil.TempDir("", "gpgme-import-test")
|
||||
checkError(t, err)
|
||||
defer os.RemoveAll(homeDir)
|
||||
|
||||
ctx, err := New()
|
||||
checkError(t, err)
|
||||
checkError(t, ctx.SetEngineInfo(ProtocolOpenPGP, "", homeDir))
|
||||
|
||||
f, err := os.Open("./testdata/pubkeys.gpg")
|
||||
checkError(t, err)
|
||||
defer f.Close()
|
||||
dh, err := NewDataFile(f)
|
||||
checkError(t, err)
|
||||
defer dh.Close()
|
||||
|
||||
res, err := ctx.Import(dh)
|
||||
checkError(t, err)
|
||||
|
||||
for _, v := range []struct {
|
||||
Name string
|
||||
Value int
|
||||
Expected int
|
||||
}{
|
||||
{"Considered", res.Considered, 1},
|
||||
{"NoUserID", res.NoUserID, 0},
|
||||
{"Imported", res.Imported, 1},
|
||||
// Do not test ImportedRSA, as of gnupg 2.1.11 the value is always 0.
|
||||
{"Unchanged", res.Unchanged, 0},
|
||||
{"NewUserIDs", res.NewUserIDs, 0},
|
||||
{"NewSubKeys", res.NewSubKeys, 0},
|
||||
{"NewSignatures", res.NewSignatures, 0},
|
||||
{"NewRevocations", res.NewRevocations, 0},
|
||||
{"SecretRead", res.SecretRead, 0},
|
||||
{"SecretImported", res.SecretImported, 0},
|
||||
{"SecretUnchanged", res.SecretUnchanged, 0},
|
||||
{"NotImported", res.NotImported, 0},
|
||||
} {
|
||||
if v.Value != v.Expected {
|
||||
t.Errorf("Unexpected import result field %s, value %d, expected %d", v.Name, v.Value, v.Expected)
|
||||
}
|
||||
}
|
||||
expectedStatus := ImportStatus{
|
||||
Fingerprint: "44B646DC347C31E867FF4F450327FFB0229F6136",
|
||||
Result: nil,
|
||||
Status: ImportNew,
|
||||
}
|
||||
if len(res.Imports) != 1 {
|
||||
t.Errorf("Unexpected number of import status values %d", len(res.Imports))
|
||||
} else if res.Imports[0] != expectedStatus {
|
||||
t.Errorf("Import status does not match: %#v vs. %#v", res.Imports[0], expectedStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func isGPG2x(t *testing.T) (bool, string) {
|
||||
var info *EngineInfo
|
||||
info, err := GetEngineInfo()
|
||||
checkError(t, err)
|
||||
for info != nil {
|
||||
if info.Protocol() == ProtocolOpenPGP {
|
||||
if strings.Contains(info.FileName(), "gpg") && strings.HasPrefix(info.Version(), "2.") {
|
||||
return true, info.FileName()
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
info = info.Next()
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func skipGPG2x(t *testing.T, msg string) {
|
||||
if isv2, gpgPath := isGPG2x(t); isv2 {
|
||||
// If this is a common Fedora location, try the v1 location as well.
|
||||
if gpgPath == "/usr/bin/gpg2" {
|
||||
if _, err := os.Stat("/usr/bin/gpg"); err == nil {
|
||||
err := SetEngineInfo(ProtocolOpenPGP, "/usr/bin/gpg", testGPGHome)
|
||||
checkError(t, err)
|
||||
}
|
||||
}
|
||||
// Test again
|
||||
if isv2, _ = isGPG2x(t); isv2 {
|
||||
t.Skip(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func diff(t *testing.T, dst, src []byte) {
|
||||
line := 1
|
||||
offs := 0 // line offset
|
||||
for i := 0; i < len(dst) && i < len(src); i++ {
|
||||
d := dst[i]
|
||||
s := src[i]
|
||||
if d != s {
|
||||
t.Errorf("dst:%d: %s\n", line, dst[offs:i+1])
|
||||
t.Errorf("src:%d: %s\n", line, src[offs:i+1])
|
||||
return
|
||||
}
|
||||
if s == '\n' {
|
||||
line++
|
||||
offs = i + 1
|
||||
}
|
||||
}
|
||||
if len(dst) != len(src) {
|
||||
t.Errorf("len(dst) = %d, len(src) = %d\nsrc = %q", len(dst), len(src), src)
|
||||
}
|
||||
}
|
||||
|
||||
func checkError(t *testing.T, err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
_, file, line, ok := runtime.Caller(1)
|
||||
if ok {
|
||||
// Truncate file name at last file name separator.
|
||||
if index := strings.LastIndex(file, "/"); index >= 0 {
|
||||
file = file[index+1:]
|
||||
} else if index = strings.LastIndex(file, "\\"); index >= 0 {
|
||||
file = file[index+1:]
|
||||
}
|
||||
} else {
|
||||
file = "???"
|
||||
line = 1
|
||||
}
|
||||
t.Fatalf("%s:%d: %s", file, line, err)
|
||||
}
|
||||
1
vendor/github.com/mtrmac/gpgme/testdata/gpghome/gpg-agent.conf
generated
vendored
Normal file
1
vendor/github.com/mtrmac/gpgme/testdata/gpghome/gpg-agent.conf
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
allow-loopback-pinentry
|
||||
0
vendor/github.com/mtrmac/gpgme/testdata/gpghome/gpg.conf
generated
vendored
Normal file
0
vendor/github.com/mtrmac/gpgme/testdata/gpghome/gpg.conf
generated
vendored
Normal file
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/pubring.gpg
generated
vendored
Normal file
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/pubring.gpg
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/secring.gpg
generated
vendored
Normal file
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/secring.gpg
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/trustdb.gpg
generated
vendored
Normal file
BIN
vendor/github.com/mtrmac/gpgme/testdata/gpghome/trustdb.gpg
generated
vendored
Normal file
Binary file not shown.
30
vendor/github.com/mtrmac/gpgme/testdata/pubkeys.gpg
generated
vendored
Normal file
30
vendor/github.com/mtrmac/gpgme/testdata/pubkeys.gpg
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mQENBFQnVRMBCADJCrvBzeItL55ZQ1jgYV5NOPo1q0O/aQzUxQ9gOMBiKkFIDWBj
|
||||
z6PrehVyYByKNkpMMVwF2VtvqA3+pW8e+0EV633y3UQvSVLNlWmYerk683HsAeyI
|
||||
GZS7oOigrX0NYOw8RsqKlz3rTXC4NbMB5m7CA+L7XdsCzH9njy9D/48RuDczywHb
|
||||
/QWCcXO+/xMt32KqZh+/wOi5bO6v+i0HuzijoKtPGRjHg3+Ar7EIlEgU4T1TYYsO
|
||||
uzB+OmNF7EAALg2Qt9BBzbTnQQl7rNWH9i+kWq13BVf9Ug+CerCB05IwNSeIU71K
|
||||
gQlIzZfY2C+040AG5GDYDPaHB1tKaPd1Yf8JABEBAAG0G1Rlc3QgS2V5IDx0ZXN0
|
||||
QGV4YW1wbGUuY29tPokBOQQTAQIAIwUCVCdVEwIbAwcLCQgHAwIBBhUIAgkKCwQW
|
||||
AgMBAh4BAheAAAoJEAMn/7Ain2E2IesH/2s61KJAyow+ZuX6ryRFlhm0irEi0m9t
|
||||
LOWa7X2qNLt31XsHSc2ZL+jRj5nnQYv7y3Fbd+gIgHb03Kap10i//ukwPbX0h+oj
|
||||
xAEKH9tTpRzYm+MKOrdfrB+OUXZBX63oYooLMTcSKxk6C6881Es8yFIDOVGCSUuu
|
||||
JUNrojPVMdRVD8MHlDPpg0SFrC4s7tLQaQ7L2sFipCPUwLuPV91ionPv7sv8q3LR
|
||||
D3O5CoaC/nl1XNIDVmXHACwyRWw/iCbQ9L7xbeiEgJkZLCQHanhbvFPMA4hFdQQX
|
||||
6qcYh6vRzOJv+UyAORfKpIu5avnqo7GziADhf4qJVxQ0sSV/DutG9765AQ0EVCdV
|
||||
EwEIALyTAnCvrjPJUeFJMR9m6cSFrTVzMrZDbyydBdNtwgZM9DNUCPe+os6p6/fq
|
||||
UVTceICHlI8ogDAIct983mfu5xb0YPvOHIc9PnPoRrRHlVcYsT4fIHeeR2YLjg3e
|
||||
6AxS/8D9Hx/FrTu9tTF1wxOuN0I8ViPKu90c8v9neCGgHkYptTj40IHXoXdlwjI7
|
||||
vkls6aXb3T4hsvRZHBeGeW2vMKXYHpw7VO3+MJWiOb7s5g2KFfKzXmf3Ir3MIOXV
|
||||
MTGMcCRfnyElv+aCaWISByNChb3xVWx2u03fJYG3/JoGg5yPieEjnSeFP1sUklSs
|
||||
dNjf/k87FsfcEvMW+63LxrIzHIcAEQEAAYkBHwQYAQIACQUCVCdVEwIbDAAKCRAD
|
||||
J/+wIp9hNmiiB/9v2CpbNuiSxpe8YSWzwsyll0OwZCespQUr9kzGRlrtYKy7Geuj
|
||||
DeE7WJS9C4ULMIS2wCpWcbeHucwrB+QylONQ5yxZeivFxR8yyZev+axGyKr3qMYI
|
||||
pPbkhlilpwWJyJV6HzIUjTfRUKVt7ySqAo4VzNjwu7r2E5IdSjecm3ywLB5hxZjZ
|
||||
dgTxUghdQYS+U6JMod55dcMzMvGm8WiZqp7CaxmfW56bgfJYxfGqL+MXEYiKB/Yl
|
||||
/S8773XlVA7g9JOPnmkuG7NpZb3onKkcmwmq0JcOQyUuClLx26DMW6wn0XBZOe1X
|
||||
WzpclcM/UTuDk7w5/PVCorGZAONowX5zB0GQ
|
||||
=TA2b
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
Loading…
Add table
Add a link
Reference in a new issue