Build and install from GOPATH

* Rename 'vendor/src' -> 'vendor'
  * Ignore vendor/ instead of vendor/src/ for lint
* Rename 'cmd/client' -> 'cmd/ocic' to make it 'go install'able
* Rename 'cmd/server' -> 'cmd/ocid' to make it 'go install'able
* Update Makefile to build and install from GOPATH
* Update tests to locate ocid/ocic in GOPATH/bin
* Search for binaries in GOPATH/bin instead of PATH
* Install tools using `go get -u`, so they are updated on each run

Signed-off-by: Jonathan Yu <jawnsy@redhat.com>
This commit is contained in:
Jonathan Yu 2017-01-17 11:57:35 -08:00
parent 9da2882d49
commit 6c9628cdb1
No known key found for this signature in database
GPG key ID: F3C2F688A21CB648
1111 changed files with 70 additions and 61 deletions

1
vendor/github.com/mtrmac/gpgme/.gitignore generated vendored Normal file
View file

@ -0,0 +1 @@
testdata/gpghome/random_seed

12
vendor/github.com/mtrmac/gpgme/LICENSE generated vendored Normal file
View 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
View 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
View 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
View 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))
}

89
vendor/github.com/mtrmac/gpgme/go_gpgme.c generated vendored Normal file
View 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
View 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
View file

@ -0,0 +1,740 @@
// Package gpgme provides a Go wrapper for the GPGME library
package gpgme
// #cgo LDFLAGS: -lgpgme -lassuan -lgpg-error
// #cgo CPPFLAGS: -D_FILE_OFFSET_BITS=64
// #include <stdlib.h>
// #include <gpgme.h>
// #include "go_gpgme.h"
import "C"
import (
"io"
"os"
"runtime"
"time"
"unsafe"
)
var Version string
func init() {
Version = C.GoString(C.gpgme_check_version(nil))
}
// Callback is the function that is called when a passphrase is required
type Callback func(uidHint string, prevWasBad bool, f *os.File) error
//export gogpgme_passfunc
func gogpgme_passfunc(hook unsafe.Pointer, uid_hint, passphrase_info *C.char, prev_was_bad, fd C.int) C.gpgme_error_t {
c := callbackLookup(uintptr(hook)).(*Context)
go_uid_hint := C.GoString(uid_hint)
f := os.NewFile(uintptr(fd), go_uid_hint)
defer f.Close()
err := c.callback(go_uid_hint, prev_was_bad != 0, f)
if err != nil {
return C.GPG_ERR_CANCELED
}
return 0
}
type Protocol int
const (
ProtocolOpenPGP Protocol = C.GPGME_PROTOCOL_OpenPGP
ProtocolCMS Protocol = C.GPGME_PROTOCOL_CMS
ProtocolGPGConf Protocol = C.GPGME_PROTOCOL_GPGCONF
ProtocolAssuan Protocol = C.GPGME_PROTOCOL_ASSUAN
ProtocolG13 Protocol = C.GPGME_PROTOCOL_G13
ProtocolUIServer Protocol = C.GPGME_PROTOCOL_UISERVER
// ProtocolSpawn Protocol = C.GPGME_PROTOCOL_SPAWN // Unavailable in 1.4.3
ProtocolDefault Protocol = C.GPGME_PROTOCOL_DEFAULT
ProtocolUnknown Protocol = C.GPGME_PROTOCOL_UNKNOWN
)
type PinEntryMode int
// const ( // Unavailable in 1.3.2
// PinEntryDefault PinEntryMode = C.GPGME_PINENTRY_MODE_DEFAULT
// PinEntryAsk PinEntryMode = C.GPGME_PINENTRY_MODE_ASK
// PinEntryCancel PinEntryMode = C.GPGME_PINENTRY_MODE_CANCEL
// PinEntryError PinEntryMode = C.GPGME_PINENTRY_MODE_ERROR
// PinEntryLoopback PinEntryMode = C.GPGME_PINENTRY_MODE_LOOPBACK
// )
type EncryptFlag uint
const (
EncryptAlwaysTrust EncryptFlag = C.GPGME_ENCRYPT_ALWAYS_TRUST
EncryptNoEncryptTo EncryptFlag = C.GPGME_ENCRYPT_NO_ENCRYPT_TO
EncryptPrepare EncryptFlag = C.GPGME_ENCRYPT_PREPARE
EncryptExceptSign EncryptFlag = C.GPGME_ENCRYPT_EXPECT_SIGN
// EncryptNoCompress EncryptFlag = C.GPGME_ENCRYPT_NO_COMPRESS // Unavailable in 1.4.3
)
type HashAlgo int
// const values for HashAlgo values should be added when necessary.
type KeyListMode uint
const (
KeyListModeLocal KeyListMode = C.GPGME_KEYLIST_MODE_LOCAL
KeyListModeExtern KeyListMode = C.GPGME_KEYLIST_MODE_EXTERN
KeyListModeSigs KeyListMode = C.GPGME_KEYLIST_MODE_SIGS
KeyListModeSigNotations KeyListMode = C.GPGME_KEYLIST_MODE_SIG_NOTATIONS
// KeyListModeWithSecret KeyListMode = C.GPGME_KEYLIST_MODE_WITH_SECRET // Unavailable in 1.4.3
KeyListModeEphemeral KeyListMode = C.GPGME_KEYLIST_MODE_EPHEMERAL
KeyListModeModeValidate KeyListMode = C.GPGME_KEYLIST_MODE_VALIDATE
)
type PubkeyAlgo int
// const values for PubkeyAlgo values should be added when necessary.
type SigMode int
const (
SigModeNormal SigMode = C.GPGME_SIG_MODE_NORMAL
SigModeDetach SigMode = C.GPGME_SIG_MODE_DETACH
SigModeClear SigMode = C.GPGME_SIG_MODE_CLEAR
)
type SigSum int
const (
SigSumValid SigSum = C.GPGME_SIGSUM_VALID
SigSumGreen SigSum = C.GPGME_SIGSUM_GREEN
SigSumRed SigSum = C.GPGME_SIGSUM_RED
SigSumKeyRevoked SigSum = C.GPGME_SIGSUM_KEY_REVOKED
SigSumKeyExpired SigSum = C.GPGME_SIGSUM_KEY_EXPIRED
SigSumSigExpired SigSum = C.GPGME_SIGSUM_SIG_EXPIRED
SigSumKeyMissing SigSum = C.GPGME_SIGSUM_KEY_MISSING
SigSumCRLMissing SigSum = C.GPGME_SIGSUM_CRL_MISSING
SigSumCRLTooOld SigSum = C.GPGME_SIGSUM_CRL_TOO_OLD
SigSumBadPolicy SigSum = C.GPGME_SIGSUM_BAD_POLICY
SigSumSysError SigSum = C.GPGME_SIGSUM_SYS_ERROR
)
type Validity int
const (
ValidityUnknown Validity = C.GPGME_VALIDITY_UNKNOWN
ValidityUndefined Validity = C.GPGME_VALIDITY_UNDEFINED
ValidityNever Validity = C.GPGME_VALIDITY_NEVER
ValidityMarginal Validity = C.GPGME_VALIDITY_MARGINAL
ValidityFull Validity = C.GPGME_VALIDITY_FULL
ValidityUltimate Validity = C.GPGME_VALIDITY_ULTIMATE
)
type ErrorCode int
const (
ErrorNoError ErrorCode = C.GPG_ERR_NO_ERROR
ErrorEOF ErrorCode = C.GPG_ERR_EOF
)
// Error is a wrapper for GPGME errors
type Error struct {
err C.gpgme_error_t
}
func (e Error) Code() ErrorCode {
return ErrorCode(C.gpgme_err_code(e.err))
}
func (e Error) Error() string {
return C.GoString(C.gpgme_strerror(e.err))
}
func handleError(err C.gpgme_error_t) error {
e := Error{err: err}
if e.Code() == ErrorNoError {
return nil
}
return e
}
func cbool(b bool) C.int {
if b {
return 1
}
return 0
}
func EngineCheckVersion(p Protocol) error {
return handleError(C.gpgme_engine_check_version(C.gpgme_protocol_t(p)))
}
type EngineInfo struct {
info C.gpgme_engine_info_t
}
func (e *EngineInfo) Next() *EngineInfo {
if e.info.next == nil {
return nil
}
return &EngineInfo{info: e.info.next}
}
func (e *EngineInfo) Protocol() Protocol {
return Protocol(e.info.protocol)
}
func (e *EngineInfo) FileName() string {
return C.GoString(e.info.file_name)
}
func (e *EngineInfo) Version() string {
return C.GoString(e.info.version)
}
func (e *EngineInfo) RequiredVersion() string {
return C.GoString(e.info.req_version)
}
func (e *EngineInfo) HomeDir() string {
return C.GoString(e.info.home_dir)
}
func GetEngineInfo() (*EngineInfo, error) {
info := &EngineInfo{}
return info, handleError(C.gpgme_get_engine_info(&info.info))
}
func SetEngineInfo(proto Protocol, fileName, homeDir string) error {
var cfn, chome *C.char
if fileName != "" {
cfn = C.CString(fileName)
defer C.free(unsafe.Pointer(cfn))
}
if homeDir != "" {
chome = C.CString(homeDir)
defer C.free(unsafe.Pointer(chome))
}
return handleError(C.gpgme_set_engine_info(C.gpgme_protocol_t(proto), cfn, chome))
}
func FindKeys(pattern string, secretOnly bool) ([]*Key, error) {
var keys []*Key
ctx, err := New()
if err != nil {
return keys, err
}
defer ctx.Release()
if err := ctx.KeyListStart(pattern, secretOnly); err != nil {
return keys, err
}
defer ctx.KeyListEnd()
for ctx.KeyListNext() {
keys = append(keys, ctx.Key)
}
if ctx.KeyError != nil {
return keys, ctx.KeyError
}
return keys, nil
}
func Decrypt(r io.Reader) (*Data, error) {
ctx, err := New()
if err != nil {
return nil, err
}
defer ctx.Release()
cipher, err := NewDataReader(r)
if err != nil {
return nil, err
}
defer cipher.Close()
plain, err := NewData()
if err != nil {
return nil, err
}
err = ctx.Decrypt(cipher, plain)
plain.Seek(0, SeekSet)
return plain, err
}
type Context struct {
Key *Key
KeyError error
callback Callback
cbc uintptr
ctx C.gpgme_ctx_t
}
func New() (*Context, error) {
c := &Context{}
err := C.gpgme_new(&c.ctx)
runtime.SetFinalizer(c, (*Context).Release)
return c, handleError(err)
}
func (c *Context) Release() {
if c.ctx == nil {
return
}
if c.cbc > 0 {
callbackDelete(c.cbc)
}
C.gpgme_release(c.ctx)
c.ctx = nil
}
func (c *Context) SetArmor(yes bool) {
C.gpgme_set_armor(c.ctx, cbool(yes))
}
func (c *Context) Armor() bool {
return C.gpgme_get_armor(c.ctx) != 0
}
func (c *Context) SetTextMode(yes bool) {
C.gpgme_set_textmode(c.ctx, cbool(yes))
}
func (c *Context) TextMode() bool {
return C.gpgme_get_textmode(c.ctx) != 0
}
func (c *Context) SetProtocol(p Protocol) error {
return handleError(C.gpgme_set_protocol(c.ctx, C.gpgme_protocol_t(p)))
}
func (c *Context) Protocol() Protocol {
return Protocol(C.gpgme_get_protocol(c.ctx))
}
func (c *Context) SetKeyListMode(m KeyListMode) error {
return handleError(C.gpgme_set_keylist_mode(c.ctx, C.gpgme_keylist_mode_t(m)))
}
func (c *Context) KeyListMode() KeyListMode {
return KeyListMode(C.gpgme_get_keylist_mode(c.ctx))
}
// Unavailable in 1.3.2:
// func (c *Context) SetPinEntryMode(m PinEntryMode) error {
// return handleError(C.gpgme_set_pinentry_mode(c.ctx, C.gpgme_pinentry_mode_t(m)))
// }
// Unavailable in 1.3.2:
// func (c *Context) PinEntryMode() PinEntryMode {
// return PinEntryMode(C.gpgme_get_pinentry_mode(c.ctx))
// }
func (c *Context) SetCallback(callback Callback) error {
var err error
c.callback = callback
if c.cbc > 0 {
callbackDelete(c.cbc)
}
if callback != nil {
cbc := callbackAdd(c)
c.cbc = cbc
_, err = C.gogpgme_set_passphrase_cb(c.ctx, C.gpgme_passphrase_cb_t(C.gogpgme_passfunc), C.uintptr_t(cbc))
} else {
c.cbc = 0
_, err = C.gogpgme_set_passphrase_cb(c.ctx, nil, 0)
}
return err
}
func (c *Context) EngineInfo() *EngineInfo {
return &EngineInfo{info: C.gpgme_ctx_get_engine_info(c.ctx)}
}
func (c *Context) SetEngineInfo(proto Protocol, fileName, homeDir string) error {
var cfn, chome *C.char
if fileName != "" {
cfn = C.CString(fileName)
defer C.free(unsafe.Pointer(cfn))
}
if homeDir != "" {
chome = C.CString(homeDir)
defer C.free(unsafe.Pointer(chome))
}
return handleError(C.gpgme_ctx_set_engine_info(c.ctx, C.gpgme_protocol_t(proto), cfn, chome))
}
func (c *Context) KeyListStart(pattern string, secretOnly bool) error {
cpattern := C.CString(pattern)
defer C.free(unsafe.Pointer(cpattern))
err := C.gpgme_op_keylist_start(c.ctx, cpattern, cbool(secretOnly))
return handleError(err)
}
func (c *Context) KeyListNext() bool {
c.Key = newKey()
err := handleError(C.gpgme_op_keylist_next(c.ctx, &c.Key.k))
if err != nil {
if e, ok := err.(Error); ok && e.Code() == ErrorEOF {
c.KeyError = nil
} else {
c.KeyError = err
}
return false
}
c.KeyError = nil
return true
}
func (c *Context) KeyListEnd() error {
return handleError(C.gpgme_op_keylist_end(c.ctx))
}
func (c *Context) GetKey(fingerprint string, secret bool) (*Key, error) {
key := newKey()
cfpr := C.CString(fingerprint)
defer C.free(unsafe.Pointer(cfpr))
return key, handleError(C.gpgme_get_key(c.ctx, cfpr, &key.k, cbool(secret)))
}
func (c *Context) Decrypt(ciphertext, plaintext *Data) error {
return handleError(C.gpgme_op_decrypt(c.ctx, ciphertext.dh, plaintext.dh))
}
func (c *Context) DecryptVerify(ciphertext, plaintext *Data) error {
return handleError(C.gpgme_op_decrypt_verify(c.ctx, ciphertext.dh, plaintext.dh))
}
type Signature struct {
Summary SigSum
Fingerprint string
Status error
Timestamp time.Time
ExpTimestamp time.Time
WrongKeyUsage bool
PKATrust uint
ChainModel bool
Validity Validity
ValidityReason error
PubkeyAlgo PubkeyAlgo
HashAlgo HashAlgo
}
func (c *Context) Verify(sig, signedText, plain *Data) (string, []Signature, error) {
var signedTextPtr, plainPtr C.gpgme_data_t = nil, nil
if signedText != nil {
signedTextPtr = signedText.dh
}
if plain != nil {
plainPtr = plain.dh
}
err := handleError(C.gpgme_op_verify(c.ctx, sig.dh, signedTextPtr, plainPtr))
if err != nil {
return "", nil, err
}
res := C.gpgme_op_verify_result(c.ctx)
sigs := []Signature{}
for s := res.signatures; s != nil; s = s.next {
sig := Signature{
Summary: SigSum(s.summary),
Fingerprint: C.GoString(s.fpr),
Status: handleError(s.status),
// s.notations not implemented
Timestamp: time.Unix(int64(s.timestamp), 0),
ExpTimestamp: time.Unix(int64(s.exp_timestamp), 0),
WrongKeyUsage: C.signature_wrong_key_usage(s) != 0,
PKATrust: uint(C.signature_pka_trust(s)),
ChainModel: C.signature_chain_model(s) != 0,
Validity: Validity(s.validity),
ValidityReason: handleError(s.validity_reason),
PubkeyAlgo: PubkeyAlgo(s.pubkey_algo),
HashAlgo: HashAlgo(s.hash_algo),
}
sigs = append(sigs, sig)
}
return C.GoString(res.file_name), sigs, nil
}
func (c *Context) Encrypt(recipients []*Key, flags EncryptFlag, plaintext, ciphertext *Data) error {
size := unsafe.Sizeof(new(C.gpgme_key_t))
recp := C.calloc(C.size_t(len(recipients)+1), C.size_t(size))
defer C.free(recp)
for i := range recipients {
ptr := (*C.gpgme_key_t)(unsafe.Pointer(uintptr(recp) + size*uintptr(i)))
*ptr = recipients[i].k
}
err := C.gpgme_op_encrypt(c.ctx, (*C.gpgme_key_t)(recp), C.gpgme_encrypt_flags_t(flags), plaintext.dh, ciphertext.dh)
return handleError(err)
}
func (c *Context) Sign(signers []*Key, plain, sig *Data, mode SigMode) error {
C.gpgme_signers_clear(c.ctx)
for _, k := range signers {
if err := handleError(C.gpgme_signers_add(c.ctx, k.k)); err != nil {
C.gpgme_signers_clear(c.ctx)
return err
}
}
return handleError(C.gpgme_op_sign(c.ctx, plain.dh, sig.dh, C.gpgme_sig_mode_t(mode)))
}
// ImportStatusFlags describes the type of ImportStatus.Status. The C API in gpgme.h simply uses "unsigned".
type ImportStatusFlags uint
const (
ImportNew ImportStatusFlags = C.GPGME_IMPORT_NEW
ImportUID ImportStatusFlags = C.GPGME_IMPORT_UID
ImportSIG ImportStatusFlags = C.GPGME_IMPORT_SIG
ImportSubKey ImportStatusFlags = C.GPGME_IMPORT_SUBKEY
ImportSecret ImportStatusFlags = C.GPGME_IMPORT_SECRET
)
type ImportStatus struct {
Fingerprint string
Result error
Status ImportStatusFlags
}
type ImportResult struct {
Considered int
NoUserID int
Imported int
ImportedRSA int
Unchanged int
NewUserIDs int
NewSubKeys int
NewSignatures int
NewRevocations int
SecretRead int
SecretImported int
SecretUnchanged int
NotImported int
Imports []ImportStatus
}
func (c *Context) Import(keyData *Data) (*ImportResult, error) {
err := handleError(C.gpgme_op_import(c.ctx, keyData.dh))
if err != nil {
return nil, err
}
res := C.gpgme_op_import_result(c.ctx)
imports := []ImportStatus{}
for s := res.imports; s != nil; s = s.next {
imports = append(imports, ImportStatus{
Fingerprint: C.GoString(s.fpr),
Result: handleError(s.result),
Status: ImportStatusFlags(s.status),
})
}
return &ImportResult{
Considered: int(res.considered),
NoUserID: int(res.no_user_id),
Imported: int(res.imported),
ImportedRSA: int(res.imported_rsa),
Unchanged: int(res.unchanged),
NewUserIDs: int(res.new_user_ids),
NewSubKeys: int(res.new_sub_keys),
NewSignatures: int(res.new_signatures),
NewRevocations: int(res.new_revocations),
SecretRead: int(res.secret_read),
SecretImported: int(res.secret_imported),
SecretUnchanged: int(res.secret_unchanged),
NotImported: int(res.not_imported),
Imports: imports,
}, nil
}
type Key struct {
k C.gpgme_key_t
}
func newKey() *Key {
k := &Key{}
runtime.SetFinalizer(k, (*Key).Release)
return k
}
func (k *Key) Release() {
C.gpgme_key_release(k.k)
k.k = nil
}
func (k *Key) Revoked() bool {
return C.key_revoked(k.k) != 0
}
func (k *Key) Expired() bool {
return C.key_expired(k.k) != 0
}
func (k *Key) Disabled() bool {
return C.key_disabled(k.k) != 0
}
func (k *Key) Invalid() bool {
return C.key_invalid(k.k) != 0
}
func (k *Key) CanEncrypt() bool {
return C.key_can_encrypt(k.k) != 0
}
func (k *Key) CanSign() bool {
return C.key_can_sign(k.k) != 0
}
func (k *Key) CanCertify() bool {
return C.key_can_certify(k.k) != 0
}
func (k *Key) Secret() bool {
return C.key_secret(k.k) != 0
}
func (k *Key) CanAuthenticate() bool {
return C.key_can_authenticate(k.k) != 0
}
func (k *Key) IsQualified() bool {
return C.key_is_qualified(k.k) != 0
}
func (k *Key) Protocol() Protocol {
return Protocol(k.k.protocol)
}
func (k *Key) IssuerSerial() string {
return C.GoString(k.k.issuer_serial)
}
func (k *Key) IssuerName() string {
return C.GoString(k.k.issuer_name)
}
func (k *Key) ChainID() string {
return C.GoString(k.k.chain_id)
}
func (k *Key) OwnerTrust() Validity {
return Validity(k.k.owner_trust)
}
func (k *Key) SubKeys() *SubKey {
if k.k.subkeys == nil {
return nil
}
return &SubKey{k: k.k.subkeys, parent: k}
}
func (k *Key) UserIDs() *UserID {
if k.k.uids == nil {
return nil
}
return &UserID{u: k.k.uids, parent: k}
}
func (k *Key) KeyListMode() KeyListMode {
return KeyListMode(k.k.keylist_mode)
}
type SubKey struct {
k C.gpgme_subkey_t
parent *Key // make sure the key is not released when we have a reference to a subkey
}
func (k *SubKey) Next() *SubKey {
if k.k.next == nil {
return nil
}
return &SubKey{k: k.k.next, parent: k.parent}
}
func (k *SubKey) Revoked() bool {
return C.subkey_revoked(k.k) != 0
}
func (k *SubKey) Expired() bool {
return C.subkey_expired(k.k) != 0
}
func (k *SubKey) Disabled() bool {
return C.subkey_disabled(k.k) != 0
}
func (k *SubKey) Invalid() bool {
return C.subkey_invalid(k.k) != 0
}
func (k *SubKey) Secret() bool {
return C.subkey_secret(k.k) != 0
}
func (k *SubKey) KeyID() string {
return C.GoString(k.k.keyid)
}
func (k *SubKey) Fingerprint() string {
return C.GoString(k.k.fpr)
}
func (k *SubKey) Created() time.Time {
if k.k.timestamp <= 0 {
return time.Time{}
}
return time.Unix(int64(k.k.timestamp), 0)
}
func (k *SubKey) Expires() time.Time {
if k.k.expires <= 0 {
return time.Time{}
}
return time.Unix(int64(k.k.expires), 0)
}
func (k *SubKey) CardNumber() string {
return C.GoString(k.k.card_number)
}
type UserID struct {
u C.gpgme_user_id_t
parent *Key // make sure the key is not released when we have a reference to a user ID
}
func (u *UserID) Next() *UserID {
if u.u.next == nil {
return nil
}
return &UserID{u: u.u.next, parent: u.parent}
}
func (u *UserID) Revoked() bool {
return C.uid_revoked(u.u) != 0
}
func (u *UserID) Invalid() bool {
return C.uid_invalid(u.u) != 0
}
func (u *UserID) Validity() Validity {
return Validity(u.u.validity)
}
func (u *UserID) UID() string {
return C.GoString(u.u.uid)
}
func (u *UserID) Name() string {
return C.GoString(u.u.name)
}
func (u *UserID) Comment() string {
return C.GoString(u.u.comment)
}
func (u *UserID) Email() string {
return C.GoString(u.u.email)
}
// This is somewhat of a horrible hack. We need to unset GPG_AGENT_INFO so that gpgme does not pass --use-agent to GPG.
// os.Unsetenv should be enough, but that only calls the underlying C library (which gpgme uses) if cgo is involved
// - and cgo can't be used in tests. So, provide this helper for test initialization.
func unsetenvGPGAgentInfo() {
v := C.CString("GPG_AGENT_INFO")
defer C.free(unsafe.Pointer(v))
C.unsetenv(v)
}