mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-13 22:21:09 +02:00
* genkey.c: Store the secret part and return the public part.
This commit is contained in:
parent
3b8cf6e497
commit
6fd5b6d5ed
@ -1,3 +1,21 @@
|
|||||||
|
2002-01-07 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* genkey.c: Store the secret part and return the public part.
|
||||||
|
|
||||||
|
2002-01-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* command.c (cmd_get_passphrase): New.
|
||||||
|
(cmd_clear_passphrase): New.
|
||||||
|
* query.c (agent_get_passphrase): New.
|
||||||
|
|
||||||
|
2002-01-02 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* genkey.c: New.
|
||||||
|
* command.c (cmd_genkey): New.
|
||||||
|
|
||||||
|
* command.c (rc_to_assuan_status): Removed and changed all callers
|
||||||
|
to use map_to_assuan_status.
|
||||||
|
|
||||||
2001-12-19 Werner Koch <wk@gnupg.org>
|
2001-12-19 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* keyformat.txt: New.
|
* keyformat.txt: New.
|
||||||
@ -50,3 +68,13 @@ Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk@openit.de>
|
|||||||
* gpg-agent.c: New.
|
* gpg-agent.c: New.
|
||||||
* Makefile.am: New.
|
* Makefile.am: New.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free software; as a special exception the author gives
|
||||||
|
unlimited permission to copy and/or distribute it, with or without
|
||||||
|
modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
This file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
@ -30,7 +30,8 @@ gpg_agent_SOURCES = \
|
|||||||
trans.c \
|
trans.c \
|
||||||
findkey.c \
|
findkey.c \
|
||||||
pksign.c \
|
pksign.c \
|
||||||
pkdecrypt.c
|
pkdecrypt.c \
|
||||||
|
genkey.c
|
||||||
|
|
||||||
gpg_agent_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a \
|
gpg_agent_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a \
|
||||||
../common/libcommon.a $(LIBGCRYPT_LIBS)
|
../common/libcommon.a $(LIBGCRYPT_LIBS)
|
||||||
|
@ -94,6 +94,9 @@ GCRY_SEXP agent_key_from_file (const unsigned char *grip);
|
|||||||
|
|
||||||
/*-- query.c --*/
|
/*-- query.c --*/
|
||||||
int agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo);
|
int agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo);
|
||||||
|
int agent_get_passphrase (char **retpass,
|
||||||
|
const char *desc, const char *prompt,
|
||||||
|
const char *errtext);
|
||||||
|
|
||||||
/*-- pksign.c --*/
|
/*-- pksign.c --*/
|
||||||
int agent_pksign (CTRL ctrl, FILE *outfp);
|
int agent_pksign (CTRL ctrl, FILE *outfp);
|
||||||
@ -102,5 +105,10 @@ int agent_pksign (CTRL ctrl, FILE *outfp);
|
|||||||
int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
|
int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
|
||||||
FILE *outfp);
|
FILE *outfp);
|
||||||
|
|
||||||
|
/*-- genkey.c --*/
|
||||||
|
int agent_genkey (CTRL ctrl,
|
||||||
|
const char *keyparam, size_t keyparmlen, FILE *outfp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*AGENT_H*/
|
#endif /*AGENT_H*/
|
||||||
|
141
agent/command.c
141
agent/command.c
@ -1,5 +1,5 @@
|
|||||||
/* command.c - gpg-agent command handler
|
/* command.c - gpg-agent command handler
|
||||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -34,7 +34,8 @@
|
|||||||
|
|
||||||
/* maximum allowed size of the inquired ciphertext */
|
/* maximum allowed size of the inquired ciphertext */
|
||||||
#define MAXLEN_CIPHERTEXT 4096
|
#define MAXLEN_CIPHERTEXT 4096
|
||||||
|
/* maximum allowed size of the key parameters */
|
||||||
|
#define MAXLEN_KEYPARAM 1024
|
||||||
|
|
||||||
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
|
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
|
||||||
|
|
||||||
@ -50,50 +51,6 @@ struct server_local_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Map GNUPG_xxx error codes to Assuan status codes
|
|
||||||
FIXME: duplicated from ../sm/server.c */
|
|
||||||
static int
|
|
||||||
rc_to_assuan_status (int rc)
|
|
||||||
{
|
|
||||||
switch (rc)
|
|
||||||
{
|
|
||||||
case 0: break;
|
|
||||||
case GNUPG_Bad_Certificate: rc = ASSUAN_Bad_Certificate; break;
|
|
||||||
case GNUPG_Bad_Certificate_Path: rc = ASSUAN_Bad_Certificate_Path; break;
|
|
||||||
case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break;
|
|
||||||
case GNUPG_No_Data: rc = ASSUAN_No_Data_Available; break;
|
|
||||||
case GNUPG_Bad_Signature: rc = ASSUAN_Bad_Signature; break;
|
|
||||||
case GNUPG_Not_Implemented: rc = ASSUAN_Not_Implemented; break;
|
|
||||||
case GNUPG_No_Agent: rc = ASSUAN_No_Agent; break;
|
|
||||||
case GNUPG_Agent_Error: rc = ASSUAN_Agent_Error; break;
|
|
||||||
case GNUPG_No_Public_Key: rc = ASSUAN_No_Public_Key; break;
|
|
||||||
case GNUPG_No_Secret_Key: rc = ASSUAN_No_Secret_Key; break;
|
|
||||||
case GNUPG_Invalid_Data: rc = ASSUAN_Invalid_Data; break;
|
|
||||||
|
|
||||||
case GNUPG_Bad_PIN:
|
|
||||||
case GNUPG_Bad_Passphrase:
|
|
||||||
rc = ASSUAN_No_Secret_Key;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GNUPG_Read_Error:
|
|
||||||
case GNUPG_Write_Error:
|
|
||||||
case GNUPG_IO_Error:
|
|
||||||
rc = ASSUAN_Server_IO_Error;
|
|
||||||
break;
|
|
||||||
case GNUPG_Out_Of_Core:
|
|
||||||
case GNUPG_Resource_Limit:
|
|
||||||
rc = ASSUAN_Server_Resource_Problem;
|
|
||||||
break;
|
|
||||||
case GNUPG_Bug:
|
|
||||||
case GNUPG_Internal_Error:
|
|
||||||
rc = ASSUAN_Server_Bug;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rc = ASSUAN_Server_Fault;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -193,7 +150,7 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
CTRL ctrl = assuan_get_pointer (ctx);
|
CTRL ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
rc = agent_pksign (ctrl, assuan_get_data_fp (ctx));
|
rc = agent_pksign (ctrl, assuan_get_data_fp (ctx));
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PKDECRYPT <options>
|
/* PKDECRYPT <options>
|
||||||
@ -216,7 +173,92 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
|
|
||||||
rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx));
|
rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx));
|
||||||
xfree (value);
|
xfree (value);
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* GENKEY
|
||||||
|
|
||||||
|
Generate a new key, store the secret part and return the public
|
||||||
|
part. Here is an example transaction:
|
||||||
|
|
||||||
|
C: GENKEY
|
||||||
|
S: INQUIRE KEYPARM
|
||||||
|
C: D (genkey (rsa (nbits 1024)))
|
||||||
|
C: END
|
||||||
|
S: D (public-key
|
||||||
|
S: D (rsa (n 326487324683264) (e 10001)))
|
||||||
|
S OK key created
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
|
||||||
|
{
|
||||||
|
CTRL ctrl = assuan_get_pointer (ctx);
|
||||||
|
int rc;
|
||||||
|
char *value;
|
||||||
|
size_t valuelen;
|
||||||
|
|
||||||
|
/* First inquire the parameters */
|
||||||
|
rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = agent_genkey (ctrl, value, valuelen, assuan_get_data_fp (ctx));
|
||||||
|
xfree (value);
|
||||||
|
return map_to_assuan_status (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* GET_PASSPHRASE <cache_id> [<error_message> <prompt> <description>]
|
||||||
|
|
||||||
|
This function is usually used to ask for a passphrase to be used
|
||||||
|
for conventional encryption, but may aslo be used by programs which
|
||||||
|
need specal handling of passphrases. This command uses a syntax
|
||||||
|
which helps clients to use the agent with minimum effort. The
|
||||||
|
agent either returns with an error or with a OK followed by the hex
|
||||||
|
encoded passphrase. Note that the length of the strings is
|
||||||
|
implicitly limited by the maximum length of a command.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *response;
|
||||||
|
char *desc, *prompt, *errtext;
|
||||||
|
|
||||||
|
/* FIXME: Parse that stuff */
|
||||||
|
desc = "We need a passphrase";
|
||||||
|
prompt = NULL;
|
||||||
|
errtext = "try again";
|
||||||
|
|
||||||
|
rc = agent_get_passphrase (&response, desc, prompt, errtext);
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
rc = assuan_set_okay_line (ctx, response);
|
||||||
|
xfree (response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map_to_assuan_status (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CLEAR_PASSPHRASE <cache_id>
|
||||||
|
|
||||||
|
may be used to invalidate the cache entry for a passphrase. The
|
||||||
|
function returns with OK even when ther eis no cached passphrase.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* fixme: no caching yet. so return with OK */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -235,6 +277,9 @@ register_commands (ASSUAN_CONTEXT ctx)
|
|||||||
{ "SETHASH", 0, cmd_sethash },
|
{ "SETHASH", 0, cmd_sethash },
|
||||||
{ "PKSIGN", 0, cmd_pksign },
|
{ "PKSIGN", 0, cmd_pksign },
|
||||||
{ "PKDECRYPT", 0, cmd_pkdecrypt },
|
{ "PKDECRYPT", 0, cmd_pkdecrypt },
|
||||||
|
{ "GENKEY", 0, cmd_genkey },
|
||||||
|
{ "GET_PASSPHRASE",0, cmd_get_passphrase },
|
||||||
|
{ "CLEAR_PASSPHRASE",0, cmd_clear_passphrase },
|
||||||
{ "", ASSUAN_CMD_INPUT, NULL },
|
{ "", ASSUAN_CMD_INPUT, NULL },
|
||||||
{ "", ASSUAN_CMD_OUTPUT, NULL },
|
{ "", ASSUAN_CMD_OUTPUT, NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
189
agent/genkey.c
Normal file
189
agent/genkey.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/* pksign.c - Generate a keypair
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "agent.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
store_key (GCRY_SEXP private)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *fname;
|
||||||
|
FILE *fp;
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
unsigned char grip[20];
|
||||||
|
char hexgrip[41];
|
||||||
|
|
||||||
|
if ( !gcry_pk_get_keygrip (private, grip) )
|
||||||
|
{
|
||||||
|
log_error ("can't calculate keygrip\n");
|
||||||
|
return seterr (General_Error);
|
||||||
|
}
|
||||||
|
for (i=0; i < 20; i++)
|
||||||
|
sprintf (hexgrip+2*i, "%02X", grip[i]);
|
||||||
|
hexgrip[40] = 0;
|
||||||
|
|
||||||
|
fname = make_filename (opt.homedir, "private-keys-v1.d", hexgrip, NULL);
|
||||||
|
if (!access (fname, F_OK))
|
||||||
|
{
|
||||||
|
log_error ("secret key file `%s' already exists - very strange\n",
|
||||||
|
fname);
|
||||||
|
xfree (fname);
|
||||||
|
return seterr (General_Error);
|
||||||
|
}
|
||||||
|
fp = fopen (fname, "wbx");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
log_error ("can't create `%s': %s\n", fname, strerror (errno));
|
||||||
|
xfree (fname);
|
||||||
|
return seterr (File_Create_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||||
|
assert (len);
|
||||||
|
buf = gcry_malloc_secure (len);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
fclose (fp);
|
||||||
|
remove (fname);
|
||||||
|
xfree (fname);
|
||||||
|
return seterr (Out_Of_Core);
|
||||||
|
}
|
||||||
|
len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len);
|
||||||
|
assert (len);
|
||||||
|
|
||||||
|
if (fwrite (buf, len, 1, fp) != 1)
|
||||||
|
{
|
||||||
|
log_error ("error writing `%s': %s\n", fname, strerror (errno));
|
||||||
|
fclose (fp);
|
||||||
|
remove (fname);
|
||||||
|
xfree (fname);
|
||||||
|
xfree (buf);
|
||||||
|
return seterr (File_Create_Error);
|
||||||
|
}
|
||||||
|
if ( fclose (fp) )
|
||||||
|
{
|
||||||
|
log_error ("error closing `%s': %s\n", fname, strerror (errno));
|
||||||
|
remove (fname);
|
||||||
|
xfree (fname);
|
||||||
|
xfree (buf);
|
||||||
|
return seterr (File_Create_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (fname);
|
||||||
|
xfree (buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Generate a new keypair according to the parameters given in
|
||||||
|
KEYPARAM */
|
||||||
|
int
|
||||||
|
agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
|
||||||
|
FILE *outfp)
|
||||||
|
{
|
||||||
|
GCRY_SEXP s_keyparam, s_key, s_private, s_public;
|
||||||
|
int rc;
|
||||||
|
size_t len;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("failed to convert keyparam: %s\n", gcry_strerror (rc));
|
||||||
|
return seterr (Invalid_Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixme: Get the passphrase now, cause key generation may take a while */
|
||||||
|
|
||||||
|
rc = gcry_pk_genkey (&s_key, s_keyparam );
|
||||||
|
gcry_sexp_release (s_keyparam);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("key generation failed: %s\n", gcry_strerror (rc));
|
||||||
|
return map_gcry_err (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* break out the parts */
|
||||||
|
s_private = gcry_sexp_find_token (s_key, "private-key", 0);
|
||||||
|
if (!s_private)
|
||||||
|
{
|
||||||
|
log_error ("key generation failed: invalid return value\n");
|
||||||
|
gcry_sexp_release (s_key);
|
||||||
|
return seterr (Invalid_Data);
|
||||||
|
}
|
||||||
|
s_public = gcry_sexp_find_token (s_key, "public-key", 0);
|
||||||
|
if (!s_public)
|
||||||
|
{
|
||||||
|
log_error ("key generation failed: invalid return value\n");
|
||||||
|
gcry_sexp_release (s_private);
|
||||||
|
gcry_sexp_release (s_key);
|
||||||
|
return seterr (Invalid_Data);
|
||||||
|
}
|
||||||
|
gcry_sexp_release (s_key); s_key = NULL;
|
||||||
|
|
||||||
|
/* store the secret key */
|
||||||
|
log_debug ("storing private key\n");
|
||||||
|
rc = store_key (s_private);
|
||||||
|
gcry_sexp_release (s_private);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (s_public);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the public key */
|
||||||
|
log_debug ("returning public key\n");
|
||||||
|
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0);
|
||||||
|
assert (len);
|
||||||
|
buf = xmalloc (len);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (s_private);
|
||||||
|
gcry_sexp_release (s_public);
|
||||||
|
return seterr (Out_Of_Core);
|
||||||
|
}
|
||||||
|
len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len);
|
||||||
|
assert (len);
|
||||||
|
if (fwrite (buf, len, 1, outfp) != 1)
|
||||||
|
{
|
||||||
|
log_error ("error writing public key: %s\n", strerror (errno));
|
||||||
|
gcry_sexp_release (s_private);
|
||||||
|
gcry_sexp_release (s_public);
|
||||||
|
xfree (buf);
|
||||||
|
return seterr (File_Create_Error);
|
||||||
|
}
|
||||||
|
gcry_sexp_release (s_public);
|
||||||
|
xfree (buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,8 @@ keyformat.txt (wk 2001-12-18)
|
|||||||
Some notes on the format of the secret keys used with gpg-agent.
|
Some notes on the format of the secret keys used with gpg-agent.
|
||||||
|
|
||||||
|
|
||||||
The secret[1] keys are store one per file in a directory below
|
The secret keys[1] are stored on a per file basis in a directory below
|
||||||
the .gnupg homedirectory. This directory is named
|
the .gnupg home directory. This directory is named
|
||||||
|
|
||||||
private-keys-v1.d
|
private-keys-v1.d
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ and should have permissions 700.
|
|||||||
|
|
||||||
The secret keys are stored in files with a name matching the
|
The secret keys are stored in files with a name matching the
|
||||||
hexadecimal representation of the keygrip[2]. The content of the file
|
hexadecimal representation of the keygrip[2]. The content of the file
|
||||||
is an S-Expression like tyhe ones used with Libgcrypt. Here is the
|
is an S-Expression like the ones used with Libgcrypt. Here is an
|
||||||
example of an unprotected file:
|
example of an unprotected file:
|
||||||
|
|
||||||
(private-key
|
(private-key
|
||||||
@ -33,7 +33,8 @@ accepted by gpg-agent with the configuration option:
|
|||||||
--allow-non-canonical-key-format.
|
--allow-non-canonical-key-format.
|
||||||
|
|
||||||
The regular way to represent the keys is in canonical representation
|
The regular way to represent the keys is in canonical representation
|
||||||
with the additional requirement of an extra object around it[3]:
|
with the additional requirement of an extra object container around
|
||||||
|
it[3]:
|
||||||
|
|
||||||
(oid.1.3.6.1.4.1.11591.2.2.2
|
(oid.1.3.6.1.4.1.11591.2.2.2
|
||||||
(keyinfo human_readable_information_to_decribe_this_key)
|
(keyinfo human_readable_information_to_decribe_this_key)
|
||||||
@ -74,8 +75,8 @@ Defined protection methods are:
|
|||||||
1.3.6.1.4.1.gnu(11591).aegypten(2)
|
1.3.6.1.4.1.gnu(11591).aegypten(2)
|
||||||
.algorithms(1).keyprotection(1).s2k3-sha1-aes-cbc(1)
|
.algorithms(1).keyprotection(1).s2k3-sha1-aes-cbc(1)
|
||||||
|
|
||||||
This uses AES in CBS mode for encryption, SHA-1 fro integrity
|
This uses AES in CBC mode for encryption, SHA-1 for integrity
|
||||||
protecion and the String to Key algorithm 3 from OpenPGP (rfc2440).
|
protection and the String to Key algorithm 3 from OpenPGP (rfc2440).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -94,6 +95,9 @@ representation) after decryption:
|
|||||||
(u #304559a..[some bytes not shown]..9b#)
|
(u #304559a..[some bytes not shown]..9b#)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
For padding reasons, random bytes are appended to this list - they can
|
||||||
|
easily be stripped by looking for the end of the list.
|
||||||
|
|
||||||
The first element is the SHA-1 hash calculated on the concatenation of the
|
The first element is the SHA-1 hash calculated on the concatenation of the
|
||||||
public key and secret key parameter lists: i.e one has to hash the
|
public key and secret key parameter lists: i.e one has to hash the
|
||||||
concatenatiohn of these 6 canonical encoded lists for RSA, including
|
concatenatiohn of these 6 canonical encoded lists for RSA, including
|
||||||
@ -112,13 +116,7 @@ the stored one - If they don't match the integrity of the key is not
|
|||||||
given.
|
given.
|
||||||
|
|
||||||
|
|
||||||
|
TODO: write a more elaborated version.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -135,4 +133,4 @@ different protocols. PKCS-15 calls this a subjectKeyHash; it can be
|
|||||||
calculate using Libgcrypt's gcry_pk_get_keygrip().
|
calculate using Libgcrypt's gcry_pk_get_keygrip().
|
||||||
|
|
||||||
[3] Even when canonical representation is required we will show the
|
[3] Even when canonical representation is required we will show the
|
||||||
S-expression here in a more readable representation.
|
S-expression here in a more readable representation.
|
||||||
|
@ -215,6 +215,82 @@ agent_askpin (const char *desc_text,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask for the passphrase using the supplied arguments. The
|
||||||
|
passphrase is returned in RETPASS as an hex encoded string to be
|
||||||
|
freed by the caller */
|
||||||
|
int
|
||||||
|
agent_get_passphrase (char **retpass, const char *desc, const char *prompt,
|
||||||
|
const char *errtext)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
struct entry_parm_s parm;
|
||||||
|
unsigned char *p, *hexstring;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*retpass = NULL;
|
||||||
|
if (opt.batch)
|
||||||
|
return GNUPG_Bad_Passphrase;
|
||||||
|
|
||||||
|
rc = start_pinentry ();
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (desc)
|
||||||
|
snprintf (line, DIM(line)-1, "SETDESC %s", desc);
|
||||||
|
else
|
||||||
|
snprintf (line, DIM(line)-1, "RESET");
|
||||||
|
line[DIM(line)-1] = 0;
|
||||||
|
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
|
||||||
|
snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt? prompt : "Passphrase");
|
||||||
|
line[DIM(line)-1] = 0;
|
||||||
|
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
|
||||||
|
if (errtext)
|
||||||
|
{
|
||||||
|
snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
|
||||||
|
line[DIM(line)-1] = 0;
|
||||||
|
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&parm, 0, sizeof parm);
|
||||||
|
parm.size = ASSUAN_LINELENGTH/2 - 5;
|
||||||
|
parm.buffer = gcry_malloc_secure (parm.size+10);
|
||||||
|
if (!parm.buffer)
|
||||||
|
return seterr (Out_Of_Core);
|
||||||
|
|
||||||
|
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
xfree (parm.buffer);
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1);
|
||||||
|
if (!hexstring)
|
||||||
|
{
|
||||||
|
xfree (parm.buffer);
|
||||||
|
return seterr (Out_Of_Core);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0, p=parm.buffer; *p; p++, i += 2)
|
||||||
|
sprintf (hexstring+i, "%02X", *p);
|
||||||
|
|
||||||
|
xfree (parm.buffer);
|
||||||
|
*retpass = hexstring;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user