Check PIN if needed

If the key is to be read from a read-protected DO, ensure that
the appropriate PIN is checked before attempting to read it. If
the PIN has not been previously verified, the GPG Agent will then
take care of it.
develop
Damien Goutte-Gattat 8 years ago
parent 12fe96409f
commit 8ccf0bd759
  1. 32
      src/gpg-util.c
  2. 3
      src/gpg-util.h
  3. 47
      src/scdtotp.c

@ -206,3 +206,35 @@ connect_to_scdaemon(assuan_context_t *ctx)
return e;
}
gpg_error_t
init_agent_environment(assuan_context_t ctx)
{
char command[64], *value;
gpg_error_t e;
struct {
const char *name;
const char *option;
} *var, env_vars[] = {
"GPG_TTY", "ttyname",
"TERM", "ttytype",
"DISPLAY", "display",
"XAUTHORITY", "xauthority",
"PINENTRY_USER_DATA", "pinentry-user-data",
NULL, NULL
};
for ( var = env_vars, e = 0; var->name && e == 0; var++ ) {
if ( (value = getenv(var->name)) ) {
if ( snprintf(command, sizeof(command), "OPTION %s=%s",
var->option, value) >= sizeof(command) )
e = gcry_error(GPG_ERR_TOO_LARGE);
e = assuan_transact(ctx, command, NULL, NULL, NULL, NULL,
NULL, NULL);
}
}
return e;
}

@ -31,6 +31,9 @@ connect_to_agent(assuan_context_t *);
gpg_error_t
connect_to_scdaemon(assuan_context_t *);
gpg_error_t
init_agent_environment(assuan_context_t);
#ifdef __cplusplus
}
#endif

@ -328,6 +328,50 @@ get_otp_key(unsigned privatedo, unsigned char *buffer, size_t len)
return e;
}
static gpg_error_t
get_serial_cb(void *arg, const char *line)
{
char *serial = (char *)arg;
if ( ! strncmp("SERIALNO ", line, 9) ) {
strcpy(serial, line + 9);
return GPG_ERR_NO_ERROR;
}
else
return GPG_ERR_NO_DATA;
}
static gpg_error_t
verify_pin(int admin)
{
assuan_context_t ctx;
gpg_error_t e;
char command[64], serial[64];
char *line;
size_t len;
if ( ! (e = connect_to_agent(&ctx)) ) {
if ( ! (e = init_agent_environment(ctx)) ) {
if ( ! (e = assuan_transact(ctx, "SCD GETATTR SERIALNO",
NULL, NULL, NULL, NULL, get_serial_cb, serial)) ) {
snprintf(command, sizeof(command), "SCD CHECKPIN %s%s",
serial, admin ? "[CHV3]" : "");
e = assuan_transact(ctx, command, NULL, NULL, NULL, NULL,
NULL, NULL);
}
}
assuan_release(ctx);
}
return e;
}
static void
print_otp(unsigned otp, unsigned digits)
{
@ -432,6 +476,9 @@ main(int argc, char **argv)
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
if ( privatedo > 2 && (e = verify_pin(privatedo == 4)) )
errx(EXIT_FAILURE, "Cannot get key from token: %s", gcry_strerror(e));
if ( (e = get_otp_key(privatedo, key, sizeof(key))) )
errx(EXIT_FAILURE, "Cannot get key from token: %s", gcry_strerror(e));

Loading…
Cancel
Save