Skip to content

Commit

Permalink
Cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroen committed Sep 21, 2015
1 parent 382ebe6 commit 5f0eec7
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 32 deletions.
6 changes: 4 additions & 2 deletions NAMESPACE
@@ -1,11 +1,13 @@
# Generated by roxygen2 (4.1.1): do not edit by hand

export(gpg_download)
export(gpg_import)
export(gpg_keylist)
export(gpg_keysearch)
export(gpg_list)
export(gpg_options)
export(gpg_search)
export(gpg_sign)
export(gpg_verify)
useDynLib(gpg,R_gpg_download)
useDynLib(gpg,R_gpg_import)
useDynLib(gpg,R_gpg_keylist)
useDynLib(gpg,R_gpg_list_options)
Expand Down
26 changes: 20 additions & 6 deletions R/verify.R → R/gpg.R
Expand Up @@ -54,25 +54,34 @@ gpg_import <- function(pubkey){
structure(as.list(out), names = c("considered", "imported", "unchanged"))
}


#' @export
#' @rdname gpg
gpg_keylist <- function(secret_only = FALSE){
gpg_list <- function(secret_only = FALSE){
gpg_keylist_internal("", secret_only, local = TRUE)
}

#' @export
#' @rdname gpg
gpg_keysearch <- function(name = ""){
gpg_search <- function(name = ""){
gpg_keylist_internal(name, secret_only = FALSE, local = FALSE)
}

#' @export
#' @useDynLib gpg R_gpg_download
#' @rdname gpg
gpg_download <- function(id = ""){
if(!identical(substring(id, 1, 2), "0x")){
filter <- paste0("0x", id);
}
.Call(R_gpg_download, filter)
}

#' @useDynLib gpg R_gpg_keylist
gpg_keylist_internal <- function(name = "", secret_only = FALSE, local = FALSE){
stopifnot(is.character(name))
stopifnot(is.logical(secret_only))
out <- .Call(R_gpg_keylist, name, secret_only, local)
names(out) <- c("keyid", "fingerprint", "name", "email", "algo", "timestamp", "expires", "pubkey")
names(out) <- c("keyid", "fingerprint", "name", "email", "algo", "timestamp", "expires")
out$timestamp <- structure(out$timestamp, class=c("POSIXct", "POSIXt"))
out$expires <- structure(out$expires, class=c("POSIXct", "POSIXt"))
data.frame(out, stringsAsFactors = FALSE)
Expand All @@ -82,9 +91,14 @@ gpg_keylist_internal <- function(name = "", secret_only = FALSE, local = FALSE){
#' @useDynLib gpg R_gpg_options R_gpg_list_options
gpg_options <- function(...){
opts <- list(...)
if(length(opts)){
if(length(names(opts))){
.Call(R_gpg_options, opts)
} else {
.Call(R_gpg_list_options)
out <- .Call(R_gpg_list_options)
args <- c(...);
if(is.character(args) && length(args) == 1L){
out <- out[[args]]
}
out
}
}
4 changes: 4 additions & 0 deletions R/onload.R
@@ -0,0 +1,4 @@
.onLoad <- function(pkg, lib){
if(!length(gpg_options()$keyserver))
try(gpg_options(keyserver="hkp://keyserver.ubuntu.com:80"))
}
19 changes: 19 additions & 0 deletions api.R
@@ -0,0 +1,19 @@
# Local keys
gpg_key_list(private_only = FALSE)
gpg_key_gen(size, name, email, expiration = NULL, comment = "", password = readline)
gpg_key_import(data, ascii_armored = TRUE)
gpg_key_delete(id)
gpg_key_export(id, ascii_armored = TRUE)

# Key server
gpg_key_search(filter)
gpg_key_receive(id)
gpg_key_publish(id, confirm = interactive())

# Authenticate
gpg_sign(message, id = gpg_options("default-key"), password = readline)
gpg_verify(message, sigfile)

# Encrypt
gpg_encrypt(message, con =, id = gpg_options("default-key"))
gpg_decrypt(ciphertext, password = readline)
13 changes: 8 additions & 5 deletions man/gpg.Rd
@@ -1,11 +1,12 @@
% Generated by roxygen2 (4.1.1): do not edit by hand
% Please edit documentation in R/verify.R
% Please edit documentation in R/gpg.R
\name{gpg utilities}
\alias{gpg}
\alias{gpg utilities}
\alias{gpg_download}
\alias{gpg_import}
\alias{gpg_keylist}
\alias{gpg_keysearch}
\alias{gpg_list}
\alias{gpg_search}
\alias{gpg_sign}
\alias{gpg_verify}
\title{PGP tools}
Expand All @@ -16,9 +17,11 @@ gpg_sign(datafile, name = "", password = readline("ENTER PASSWORD: "))

gpg_import(pubkey)

gpg_keylist(secret_only = FALSE)
gpg_list(secret_only = FALSE)

gpg_keysearch(name = "")
gpg_search(name = "")

gpg_download(id = "")
}
\arguments{
\item{sigfile}{path to the gpg file containing the \code{PGP SIGNATURE} block.}
Expand Down
68 changes: 49 additions & 19 deletions src/wrapper.c
Expand Up @@ -158,7 +158,6 @@ SEXP R_gpg_keylist(SEXP filter, SEXP secret_only, SEXP local) {
SEXP algo = PROTECT(allocVector(STRSXP, count));
SEXP timestamp = PROTECT(allocVector(INTSXP, count));
SEXP expires = PROTECT(allocVector(INTSXP, count));
SEXP keydata = PROTECT(allocVector(STRSXP, count));

gpgme_key_t key;
for(int i = 0; i < count; i++){
Expand All @@ -174,20 +173,6 @@ SEXP R_gpg_keylist(SEXP filter, SEXP secret_only, SEXP local) {
if(key->uids && key->uids->email)
SET_STRING_ELT(email, i, mkChar(key->uids->email));

/* export the public key */
gpgme_data_t dh = NULL;
assert(gpgme_data_new (&dh), "initiating data buffer");
gpgme_export_mode_t mode = 0;
gpgme_key_t keyarray[2] = {key, NULL};
gpgme_set_armor (ctx, 1);
gpgme_op_export_keys(ctx, keyarray, mode, dh);

char buf[100000];
assert(gpgme_data_seek (dh, 0, SEEK_SET), "data seek");
size_t size = gpgme_data_read (dh, buf, 99999);
assert(size > -1, "data read");
SET_STRING_ELT(keydata, i, mkCharLen(buf, size));

INTEGER(timestamp)[i] = (key->subkeys->timestamp > 0) ? key->subkeys->timestamp : NA_INTEGER;
INTEGER(expires)[i] = (key->subkeys->expires > 0) ? key->subkeys->expires : NA_INTEGER;

Expand All @@ -197,16 +182,15 @@ SEXP R_gpg_keylist(SEXP filter, SEXP secret_only, SEXP local) {
free(keys);
}

SEXP result = PROTECT(allocVector(VECSXP, 8));
SEXP result = PROTECT(allocVector(VECSXP, 7));
SET_VECTOR_ELT(result, 0, keyid);
SET_VECTOR_ELT(result, 1, fpr);
SET_VECTOR_ELT(result, 2, name);
SET_VECTOR_ELT(result, 3, email);
SET_VECTOR_ELT(result, 4, algo);
SET_VECTOR_ELT(result, 5, timestamp);
SET_VECTOR_ELT(result, 6, expires);
SET_VECTOR_ELT(result, 7, keydata);
UNPROTECT(9);
UNPROTECT(8);
return result;
}

Expand Down Expand Up @@ -361,4 +345,50 @@ SEXP R_gpg_options(SEXP input){
//save config
assert(gpgme_op_conf_save (ctx, comp), "conf save");
return res;
}
}


SEXP R_gpg_download(SEXP filter) {
gpgme_keylist_mode_t mode = 0;
mode |= GPGME_KEYLIST_MODE_EXTERN;
mode |= GPGME_KEYLIST_MODE_SIGS;
mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS;
gpgme_set_keylist_mode (ctx, mode);
gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP);

//init search
assert(gpgme_op_keylist_start (ctx, CHAR(STRING_ELT(filter, 0)), 0), "starting keylist");

//load key
gpgme_key_t key;
gpgme_error_t err = gpgme_op_keylist_next (ctx, &key);
if(gpg_err_code (err) == GPG_ERR_EOF){
Rf_error("Key not found.");
}
assert(err, "getting key");
if(gpg_err_code(gpgme_op_keylist_next (ctx, NULL)) == GPG_ERR_EOF){
gpgme_op_keylist_end(ctx);
Rf_error("Multiple keys found! Please be more specific.");
}

//output block
SEXP result = PROTECT(allocVector(STRSXP, 1));
setAttrib(result, install("keyid"), mkString(key->subkeys->keyid));
setAttrib(result, install("fingerprint"), mkString(key->subkeys->keyid));

/* export the public key */
gpgme_data_t dh = NULL;
assert(gpgme_data_new (&dh), "initiating data buffer");
gpgme_export_mode_t emode = 0;
gpgme_key_t keyarray[2] = {key, NULL};
gpgme_set_armor (ctx, 1);
gpgme_op_export_keys(ctx, keyarray, emode, dh);

char buf[100000];
assert(gpgme_data_seek (dh, 0, SEEK_SET), "data seek");
size_t size = gpgme_data_read (dh, buf, 99999);
assert(size > -1, "data read");
SET_STRING_ELT(result, 0, mkCharLen(buf, size));
UNPROTECT(1);
return result;
}

0 comments on commit 5f0eec7

Please sign in to comment.