/* ------------------ * check if a key is locally available * ------------------ */ int is_key_available(const char* fpr,int secret, int servermode, char** userid) { gpgme_error_t error; gpgme_ctx_t ctx; gpgme_key_t key; gpgme_key_t key_arr[2]; gpgme_keylist_mode_t current_keylist_mode; key_arr[0] = NULL; key_arr[1] = NULL; // connect to gpgme gpgme_check_version (NULL); error = gpgme_new(&ctx); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); return FALSE; } // set to server search mode if servermode == TRUE if (servermode == TRUE) { purple_debug_info(PLUGIN_ID,"set keylist mode to server\n"); current_keylist_mode = gpgme_get_keylist_mode(ctx); gpgme_set_keylist_mode(ctx,(current_keylist_mode | GPGME_KEYLIST_MODE_EXTERN) &(~GPGME_KEYLIST_MODE_LOCAL)); } // get key by fingerprint error = gpgme_get_key(ctx,fpr,&key,secret); if (error || !key) { purple_debug_error(PLUGIN_ID,"gpgme_get_key failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return FALSE; } // if we have parameter, tell caller about userid if (userid != NULL) { *userid = g_strdup(key->uids->uid); } // import key key_arr[0] = key; error = gpgme_op_import_keys (ctx, key_arr); if (error) { purple_debug_error(PLUGIN_ID,"gpgme_op_import_keys failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (ctx); return FALSE; } // close gpgme connection gpgme_release (ctx); // we got the key, YEAH :) return TRUE; }
int main(void) { gpgme_ctx_t ctx; gpgme_error_t err; int setup_res = setup(&ctx); if(setup_res) return setup_res; /* Change mode to list sigs and */ gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx); mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS; err = gpgme_set_keylist_mode(ctx, mode); if (err != GPG_ERR_NO_ERROR) return 6; /* List all keys */ /* (context, pattern, secret_only) */ err = gpgme_op_keylist_start(ctx, NULL, 0); if (err != GPG_ERR_NO_ERROR) return 7; gpgme_key_t key; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { printf("Got a key\n"); printf ("%s:", key->subkeys->keyid); if (key->uids && key->uids->name) printf (" %s", key->uids->name); if (key->uids && key->uids->email) printf (" <%s>", key->uids->email); if (key->uids && key->uids->signatures) { printf("First signature: %s\n", key->uids->signatures->keyid); } putchar ('\n'); gpgme_key_release (key); } if (gpg_err_code(err) == GPG_ERR_EOF) { printf("%xu\n", err); printf("End of keylist.\n"); } else { print_gpg_error(err); return 8; } /* free context */ gpgme_release(ctx); return 0; }
int gpg_list_keys(key_entry_t **head) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_keylist_mode_t mode = 0; *head = 0; err = gpgme_new(&ctx); if (err) { return 0; } gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); gpgme_set_keylist_mode(ctx, mode); err = gpgme_op_keylist_start(ctx, 0, 0); if (err) { return 0; } int count = 0; key_entry_t *key_entry_prev = 0; while (1) { gpgme_key_t key; err = gpgme_op_keylist_next(ctx, &key); if (err) { break; } key_entry_t *key_entry = g_new(key_entry_t, 1); key_entry->next = 0; key_entry->key = key; if (key_entry_prev) key_entry_prev->next = key_entry; key_entry_prev = key_entry; if (!*head) *head = key_entry; ++count; } gpgme_op_keylist_end(ctx); gpgme_release(ctx); return count; }
static int pygpgme_context_set_keylist_mode(PyGpgmeContext *self, PyObject *value) { gpgme_keylist_mode_t keylist_mode; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } keylist_mode = PyInt_AsLong(value); if (PyErr_Occurred()) return -1; if (pygpgme_check_error(gpgme_set_keylist_mode(self->ctx, keylist_mode))) return -1; return 0; }
/** * Search for a GPG key in a remote location. * This requires GPGME to call the gpg binary and have a keyserver previously * defined in a gpg.conf configuration file. * @param handle the context handle * @param fpr the fingerprint key ID to look up * @param pgpkey storage location for the given key if found * @return 1 on success, 0 on key not found, -1 on error */ static int key_search(alpm_handle_t *handle, const char *fpr, alpm_pgpkey_t *pgpkey) { gpgme_error_t gpg_err; gpgme_ctx_t ctx; gpgme_keylist_mode_t mode; gpgme_key_t key; int ret = -1; size_t fpr_len; char *full_fpr; /* gpg2 goes full retard here. For key searches ONLY, we need to prefix the * key fingerprint with 0x, or the lookup will fail. */ fpr_len = strlen(fpr); MALLOC(full_fpr, fpr_len + 3, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); sprintf(full_fpr, "0x%s", fpr); memset(&ctx, 0, sizeof(ctx)); gpg_err = gpgme_new(&ctx); CHECK_ERR(); mode = gpgme_get_keylist_mode(ctx); /* using LOCAL and EXTERN together doesn't work for GPG 1.X. Ugh. */ mode &= ~GPGME_KEYLIST_MODE_LOCAL; mode |= GPGME_KEYLIST_MODE_EXTERN; gpg_err = gpgme_set_keylist_mode(ctx, mode); CHECK_ERR(); _alpm_log(handle, ALPM_LOG_DEBUG, "looking up key %s remotely\n", fpr); gpg_err = gpgme_get_key(ctx, full_fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); /* Try an alternate lookup using the 8 character fingerprint value, since * busted-ass keyservers can't support lookups using subkeys with the full * value as of now. This is why 2012 is not the year of PGP encryption. */ if(fpr_len > 8) { const char *short_fpr = memcpy(&full_fpr[fpr_len - 8], "0x", 2); _alpm_log(handle, ALPM_LOG_DEBUG, "looking up key %s remotely\n", short_fpr); gpg_err = gpgme_get_key(ctx, short_fpr, &key, 0); if(gpg_err_code(gpg_err) == GPG_ERR_EOF) { _alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n"); ret = 0; } } else { ret = 0; } } CHECK_ERR(); /* should only get here if key actually exists */ pgpkey->data = key; if(key->subkeys->fpr) { pgpkey->fingerprint = key->subkeys->fpr; } else if(key->subkeys->keyid) { pgpkey->fingerprint = key->subkeys->keyid; } pgpkey->uid = key->uids->uid; pgpkey->name = key->uids->name; pgpkey->email = key->uids->email; pgpkey->created = key->subkeys->timestamp; pgpkey->expires = key->subkeys->expires; pgpkey->length = key->subkeys->length; pgpkey->revoked = key->subkeys->revoked; switch(key->subkeys->pubkey_algo) { case GPGME_PK_RSA: case GPGME_PK_RSA_E: case GPGME_PK_RSA_S: pgpkey->pubkey_algo = 'R'; break; case GPGME_PK_DSA: pgpkey->pubkey_algo = 'D'; break; case GPGME_PK_ELG_E: case GPGME_PK_ELG: case GPGME_PK_ECDSA: case GPGME_PK_ECDH: pgpkey->pubkey_algo = 'E'; break; } ret = 1; gpg_error: if(ret != 1) { _alpm_log(handle, ALPM_LOG_DEBUG, "gpg error: %s\n", gpgme_strerror(gpg_err)); } free(full_fpr); gpgme_release(ctx); return ret; }
QString QalfCrypto::sign(QString &message, QString &key) { gpgme_key_t gpgkey ; gpgme_data_t signature ; gpgme_data_t msg ; gpgme_verify_result_t verification ; gpgme_signature_t signatures ; gpgme_error_t result ; char * buffer ; gpgme_set_passphrase_cb(context,&passphrase_callback,NULL) ; result = gpgme_set_protocol(context,GPGME_PROTOCOL_OpenPGP) ; Q_ASSERT(gpgme_err_code(result) == GPG_ERR_NO_ERROR) ; gpgme_set_armor(context,1) ; gpgme_set_textmode(context,1) ; gpgme_signers_clear(context) ; result = gpgme_set_keylist_mode(context,GPGME_KEYLIST_MODE_LOCAL) ; // retrieving key result = gpgme_get_key(context, key.toAscii().data(),&gpgkey,1) ; Q_ASSERT(result == GPG_ERR_NO_ERROR) ; Q_ASSERT(gpgkey != 0) ; // signing result = gpgme_signers_add(context,gpgkey) ; Q_ASSERT(result == GPG_ERR_NO_ERROR) ; result = gpgme_data_new(&signature); Q_ASSERT(result == GPG_ERR_NO_ERROR) ; int message_length = message.toAscii().size() ; char * message_char = (char *) calloc(message_length+1,sizeof(char)) ; memcpy(message_char,message.toAscii().data(),message_length) ; // printf("memcmp : %d\n",memcmp(message_char,"1fc36e1d41a93c1d79f6872198f426129320d287",message_length+1)) ; result = gpgme_data_new_from_mem(&msg,message_char,message_length,0) ; gpgme_data_seek(signature,0,SEEK_SET) ; gpgme_data_seek(msg,0,SEEK_SET) ; result = gpgme_op_sign(context, msg,signature, GPGME_SIG_MODE_DETACH) ; Q_ASSERT(gpgme_err_code(result) == GPG_ERR_NO_ERROR || gpgme_err_code(result) == GPG_ERR_BAD_PASSPHRASE || gpgme_err_code(result) == GPG_ERR_CANCELED) ; // gpgme_data_seek(signature,0,SEEK_SET) ; // gpgme_data_seek(msg,0,SEEK_SET) ; // // result = gpgme_op_verify (context, signature, msg , 0) ; // Q_ASSERT(gpgme_err_code(result) != GPG_ERR_INV_VALUE) ; // Q_ASSERT(gpgme_err_code(result) != GPG_ERR_NO_DATA) ; // Q_ASSERT(result == GPG_ERR_NO_ERROR) ; // // verification = gpgme_op_verify_result(context) ; // Q_ASSERT(verification != 0) ; // // signatures = verification->signatures ; // Q_ASSERT(verification->signatures != 0) ; // result = signatures->status ; // printf("status : %d\n",gpgme_err_code(result)) ; // printf("signature summary : %d\n",signatures->summary) ; // Q_ASSERT(signatures->summary == GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN) ; // QString signatureStr ; buffer = (char *) calloc(2048,sizeof(char)) ; gpgme_data_seek(signature,0,SEEK_SET) ; gpgme_data_read(signature,buffer,2048) ; signatureStr += buffer ; qDebug() << "signature" << signatureStr ; gpgme_data_release(signature) ; gpgme_key_unref(gpgkey) ; gpgme_data_release(msg) ; return signatureStr ; }
SEXP R_gpg_keylist(SEXP filter, SEXP secret_only, SEXP local) { gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx); mode |= asLogical(local) ? GPGME_KEYLIST_MODE_LOCAL : 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); //gpgme_set_global_flag("auto-key-locate", "hkp://pgp.mit.edu"); bail(gpgme_op_keylist_start (ctx, CHAR(STRING_ELT(filter, 0)), asLogical(secret_only)), "starting keylist"); struct keylist *keys = (struct keylist *) malloc(sizeof(struct keylist)); struct keylist *head = keys; gpgme_error_t err; int count = 0; while(1){ err = gpgme_op_keylist_next (ctx, &(keys->key)); if(gpg_err_code (err) == GPG_ERR_EOF) break; bail(err, "getting next key"); keys->next = (struct keylist *) malloc(sizeof(struct keylist)); keys = keys->next; count++; } /* convert the linked list into vectors */ SEXP keyid = PROTECT(allocVector(STRSXP, count)); SEXP fpr = PROTECT(allocVector(STRSXP, count)); SEXP name = PROTECT(allocVector(STRSXP, count)); SEXP email = PROTECT(allocVector(STRSXP, count)); SEXP algo = PROTECT(allocVector(STRSXP, count)); SEXP timestamp = PROTECT(allocVector(INTSXP, count)); SEXP expires = PROTECT(allocVector(INTSXP, count)); gpgme_key_t key; for(int i = 0; i < count; i++){ key = head->key; SET_STRING_ELT(keyid, i, make_char(key->subkeys->keyid)); SET_STRING_ELT(fpr, i, make_char(key->subkeys->fpr)); SET_STRING_ELT(algo, i, make_char(gpgme_pubkey_algo_name(key->subkeys->pubkey_algo))); if(key->issuer_name) SET_STRING_ELT(fpr, i, make_char(key->issuer_name)); if(key->uids && key->uids->name) SET_STRING_ELT(name, i, make_char(key->uids->name)); if(key->uids && key->uids->email) SET_STRING_ELT(email, i, make_char(key->uids->email)); INTEGER(timestamp)[i] = (key->subkeys->timestamp > 0) ? key->subkeys->timestamp : NA_INTEGER; INTEGER(expires)[i] = (key->subkeys->expires > 0) ? key->subkeys->expires : NA_INTEGER; keys = head; head = head->next; gpgme_key_unref (key); free(keys); } 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); UNPROTECT(8); return result; }
int main(void) { gpgme_ctx_t ctx; gpgme_error_t err; int setup_res = setup(&ctx); if(setup_res) return setup_res; /* Change mode to extern */ gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx); mode &= ~GPGME_KEYLIST_MODE_LOCAL; mode |= GPGME_KEYLIST_MODE_EXTERN; mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS; err = gpgme_set_keylist_mode(ctx, mode); if (err != GPG_ERR_NO_ERROR) return 6; /* List all keys */ /* (context, pattern, secret_only) */ err = gpgme_op_keylist_start(ctx, "07E7871B", 0); if (err != GPG_ERR_NO_ERROR) return 7; gpgme_key_t key; size_t MAX_KEYS = 100; gpgme_key_t keyarray[MAX_KEYS+1]; // need a space for the NULL term size_t i = 0; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { printf("Got a key\n"); printf ("%s:", key->subkeys->keyid); if (key->uids && key->uids->name) printf (" %s", key->uids->name); if (key->uids && key->uids->email) printf (" <%s>", key->uids->email); if (key->uids && key->uids->signatures) { printf("First signature: %s\n", key->uids->signatures->keyid); } putchar ('\n'); if (i < MAX_KEYS) { keyarray[i++] = key; } else { printf("Too many keys, skipping a key\n"); } //gpgme_key_release (key); } if (gpg_err_code(err) == GPG_ERR_EOF) { printf("%xu\n", err); printf("End of keylist.\n"); } else { print_gpg_error(err); return 8; } // https://bugs.gnupg.org/gnupg/issue1670 printf("Attempting to import %lu keys\n", i); err = gpgme_op_import_keys(ctx, keyarray); if (err != GPG_ERR_NO_ERROR) return 9; gpgme_import_result_t impres = gpgme_op_import_result(ctx); if (!impres) return 10; print_import_result(impres); /* free keys */ for (i = 0; keyarray[i]; i++) gpgme_key_release(key); /* free context */ gpgme_release(ctx); return 0; }