mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
Bug in blowfish behoben
This commit is contained in:
parent
6e0fd3df65
commit
0d9ffec5ef
@ -22,6 +22,12 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Test values:
|
||||||
|
* key "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
* plain "BLOWFISH"
|
||||||
|
* cipher 32 4E D0 FE F4 13 A2 03
|
||||||
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -224,25 +230,26 @@ static const u32 ps[BLOWFISH_ROUNDS+2] = {
|
|||||||
static u32
|
static u32
|
||||||
function_F( BLOWFISH_context *bc, u32 x )
|
function_F( BLOWFISH_context *bc, u32 x )
|
||||||
{
|
{
|
||||||
u16 a, b, c, d, y;
|
u16 a, b, c, d;
|
||||||
|
|
||||||
d = x & 0x00ff;
|
#ifdef BIG_ENDIAN_HOST
|
||||||
x >>= 8;
|
a = ((byte*)&x)[0];
|
||||||
c = x & 0x00ff;
|
b = ((byte*)&x)[1];
|
||||||
x >>= 8;
|
c = ((byte*)&x)[2];
|
||||||
b = x & 0x00ff;
|
d = ((byte*)&x)[3];
|
||||||
x >>= 8;
|
#else
|
||||||
a = x & 0x00ff;
|
a = ((byte*)&x)[3];
|
||||||
y = bc->s0[a] + bc->s1[b];
|
b = ((byte*)&x)[2];
|
||||||
y ^= bc->s2[c];
|
c = ((byte*)&x)[1];
|
||||||
y += bc->s3[d];
|
d = ((byte*)&x)[0];
|
||||||
|
#endif
|
||||||
|
|
||||||
return y;
|
return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
encrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
||||||
{
|
{
|
||||||
u32 xl, xr, temp;
|
u32 xl, xr, temp;
|
||||||
int i;
|
int i;
|
||||||
@ -269,8 +276,9 @@ encrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
|||||||
*ret_xr = xr;
|
*ret_xr = xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
||||||
{
|
{
|
||||||
u32 xl, xr, temp;
|
u32 xl, xr, temp;
|
||||||
int i;
|
int i;
|
||||||
@ -298,35 +306,108 @@ decrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
encrypted_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
|
encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
|
||||||
{
|
{
|
||||||
u32 d1, d2;
|
u32 d1, d2;
|
||||||
|
|
||||||
d1 = ((u32*)inbuf)[0];
|
#ifdef BIG_ENDIAN_HOST
|
||||||
|
d1 = ((u32*)inbuf)[0]; /* fixme: this may not be aligned */
|
||||||
d2 = ((u32*)inbuf)[1];
|
d2 = ((u32*)inbuf)[1];
|
||||||
encrypted( bc, &d1, &d2 );
|
#else
|
||||||
|
((byte*)&d1)[3] = inbuf[0];
|
||||||
|
((byte*)&d1)[2] = inbuf[1];
|
||||||
|
((byte*)&d1)[1] = inbuf[2];
|
||||||
|
((byte*)&d1)[0] = inbuf[3];
|
||||||
|
((byte*)&d2)[3] = inbuf[4];
|
||||||
|
((byte*)&d2)[2] = inbuf[5];
|
||||||
|
((byte*)&d2)[1] = inbuf[6];
|
||||||
|
((byte*)&d2)[0] = inbuf[7];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
encrypt( bc, &d1, &d2 );
|
||||||
|
|
||||||
|
#ifdef BIG_ENDIAN_HOST
|
||||||
((u32*)outbuf)[0] = d1;
|
((u32*)outbuf)[0] = d1;
|
||||||
((u32*)outbuf)[1] = d2;
|
((u32*)outbuf)[1] = d2;
|
||||||
|
#else
|
||||||
|
outbuf[0] = ((byte*)&d1)[3];
|
||||||
|
outbuf[1] = ((byte*)&d1)[2];
|
||||||
|
outbuf[2] = ((byte*)&d1)[1];
|
||||||
|
outbuf[3] = ((byte*)&d1)[0];
|
||||||
|
outbuf[4] = ((byte*)&d2)[3];
|
||||||
|
outbuf[5] = ((byte*)&d2)[2];
|
||||||
|
outbuf[6] = ((byte*)&d2)[1];
|
||||||
|
outbuf[7] = ((byte*)&d2)[0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decrypted_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
|
decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
|
||||||
{
|
{
|
||||||
u32 d1, d2;
|
u32 d1, d2;
|
||||||
|
|
||||||
d1 = ((u32*)inbuf)[0];
|
#ifdef BIG_ENDIAN_HOST
|
||||||
|
d1 = ((u32*)inbuf)[0]; /* fixme: this may not be aligned */
|
||||||
d2 = ((u32*)inbuf)[1];
|
d2 = ((u32*)inbuf)[1];
|
||||||
decrypted( bc, &d1, &d2 );
|
#else
|
||||||
|
((byte*)&d1)[3] = inbuf[0];
|
||||||
|
((byte*)&d1)[2] = inbuf[1];
|
||||||
|
((byte*)&d1)[1] = inbuf[2];
|
||||||
|
((byte*)&d1)[0] = inbuf[3];
|
||||||
|
((byte*)&d2)[3] = inbuf[4];
|
||||||
|
((byte*)&d2)[2] = inbuf[5];
|
||||||
|
((byte*)&d2)[1] = inbuf[6];
|
||||||
|
((byte*)&d2)[0] = inbuf[7];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
decrypt( bc, &d1, &d2 );
|
||||||
|
|
||||||
|
#ifdef BIG_ENDIAN_HOST
|
||||||
((u32*)outbuf)[0] = d1;
|
((u32*)outbuf)[0] = d1;
|
||||||
((u32*)outbuf)[1] = d2;
|
((u32*)outbuf)[1] = d2;
|
||||||
|
#else
|
||||||
|
outbuf[0] = ((byte*)&d1)[3];
|
||||||
|
outbuf[1] = ((byte*)&d1)[2];
|
||||||
|
outbuf[2] = ((byte*)&d1)[1];
|
||||||
|
outbuf[3] = ((byte*)&d1)[0];
|
||||||
|
outbuf[4] = ((byte*)&d2)[3];
|
||||||
|
outbuf[5] = ((byte*)&d2)[2];
|
||||||
|
outbuf[6] = ((byte*)&d2)[1];
|
||||||
|
outbuf[7] = ((byte*)&d2)[0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
selftest()
|
||||||
|
{
|
||||||
|
BLOWFISH_context c;
|
||||||
|
byte plain[] = "BLOWFISH";
|
||||||
|
byte buffer[8];
|
||||||
|
|
||||||
|
blowfish_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
|
||||||
|
encrypt_block( &c, buffer, plain );
|
||||||
|
if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
|
||||||
|
log_error("wrong blowfish encryption\n");
|
||||||
|
decrypt_block( &c, buffer, buffer );
|
||||||
|
if( memcmp( buffer, plain, 8 ) )
|
||||||
|
log_bug("blowfish failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
u32 data, datal, datar;
|
u32 data, datal, datar;
|
||||||
|
static int initialized;
|
||||||
|
|
||||||
|
if( !initialized ) {
|
||||||
|
initialized = 1;
|
||||||
|
selftest();
|
||||||
|
}
|
||||||
|
|
||||||
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
|
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
|
||||||
c->p[i] = ps[i];
|
c->p[i] = ps[i];
|
||||||
@ -338,38 +419,44 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) {
|
for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) {
|
||||||
data = 0;
|
#ifdef BIG_ENDIAN_HOST
|
||||||
for(k=0; k < 4; k++) {
|
((byte*)&data)[0] = key[j];
|
||||||
data = (data << 8) | key[j];
|
((byte*)&data)[1] = key[(j+1)%keylen];
|
||||||
if( ++j >= keylen )
|
((byte*)&data)[2] = key[(j+2)%keylen];
|
||||||
j = 0;
|
((byte*)&data)[3] = key[(j+3)%keylen];
|
||||||
}
|
#else
|
||||||
|
((byte*)&data)[3] = key[j];
|
||||||
|
((byte*)&data)[2] = key[(j+1)%keylen];
|
||||||
|
((byte*)&data)[1] = key[(j+2)%keylen];
|
||||||
|
((byte*)&data)[0] = key[(j+3)%keylen];
|
||||||
|
#endif
|
||||||
c->p[i] ^= data;
|
c->p[i] ^= data;
|
||||||
|
j = (j+4) % keylen;
|
||||||
}
|
}
|
||||||
|
|
||||||
datal = datar = 0;
|
datal = datar = 0;
|
||||||
for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 ) {
|
for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 ) {
|
||||||
encrypted( c, &datal, &datar );
|
encrypt( c, &datal, &datar );
|
||||||
c->p[i] = datal;
|
c->p[i] = datal;
|
||||||
c->p[i+1] = datar;
|
c->p[i+1] = datar;
|
||||||
}
|
}
|
||||||
for(i=0; i < 256; i += 2 ) {
|
for(i=0; i < 256; i += 2 ) {
|
||||||
encrypted( c, &datal, &datar );
|
encrypt( c, &datal, &datar );
|
||||||
c->s0[i] = datal;
|
c->s0[i] = datal;
|
||||||
c->s0[i+1] = datar;
|
c->s0[i+1] = datar;
|
||||||
}
|
}
|
||||||
for(i=0; i < 256; i += 2 ) {
|
for(i=0; i < 256; i += 2 ) {
|
||||||
encrypted( c, &datal, &datar );
|
encrypt( c, &datal, &datar );
|
||||||
c->s1[i] = datal;
|
c->s1[i] = datal;
|
||||||
c->s1[i+1] = datar;
|
c->s1[i+1] = datar;
|
||||||
}
|
}
|
||||||
for(i=0; i < 256; i += 2 ) {
|
for(i=0; i < 256; i += 2 ) {
|
||||||
encrypted( c, &datal, &datar );
|
encrypt( c, &datal, &datar );
|
||||||
c->s2[i] = datal;
|
c->s2[i] = datal;
|
||||||
c->s2[i+1] = datar;
|
c->s2[i+1] = datar;
|
||||||
}
|
}
|
||||||
for(i=0; i < 256; i += 2 ) {
|
for(i=0; i < 256; i += 2 ) {
|
||||||
encrypted( c, &datal, &datar );
|
encrypt( c, &datal, &datar );
|
||||||
c->s3[i] = datal;
|
c->s3[i] = datal;
|
||||||
c->s3[i+1] = datar;
|
c->s3[i+1] = datar;
|
||||||
}
|
}
|
||||||
@ -384,7 +471,7 @@ blowfish_setiv( BLOWFISH_context *c, byte *iv )
|
|||||||
else
|
else
|
||||||
memset( c->iv, 0, BLOWFISH_BLOCKSIZE );
|
memset( c->iv, 0, BLOWFISH_BLOCKSIZE );
|
||||||
c->count = 0;
|
c->count = 0;
|
||||||
encrypted_block( c, c->eniv, c->iv );
|
encrypt_block( c, c->eniv, c->iv );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -395,7 +482,7 @@ blowfish_encode( BLOWFISH_context *c, byte *outbuf, byte *inbuf,
|
|||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
for(n=0; n < nblocks; n++ ) {
|
for(n=0; n < nblocks; n++ ) {
|
||||||
encrypted_block( c, outbuf, inbuf );
|
encrypt_block( c, outbuf, inbuf );
|
||||||
inbuf += BLOWFISH_BLOCKSIZE;;
|
inbuf += BLOWFISH_BLOCKSIZE;;
|
||||||
outbuf += BLOWFISH_BLOCKSIZE;
|
outbuf += BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
@ -408,7 +495,7 @@ blowfish_decode( BLOWFISH_context *c, byte *outbuf, byte *inbuf,
|
|||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
for(n=0; n < nblocks; n++ ) {
|
for(n=0; n < nblocks; n++ ) {
|
||||||
decrypted_block( c, outbuf, inbuf );
|
decrypt_block( c, outbuf, inbuf );
|
||||||
inbuf += BLOWFISH_BLOCKSIZE;;
|
inbuf += BLOWFISH_BLOCKSIZE;;
|
||||||
outbuf += BLOWFISH_BLOCKSIZE;
|
outbuf += BLOWFISH_BLOCKSIZE;
|
||||||
}
|
}
|
||||||
@ -451,7 +538,7 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf,
|
|||||||
outbuf += n;
|
outbuf += n;
|
||||||
assert( c->count <= BLOWFISH_BLOCKSIZE);
|
assert( c->count <= BLOWFISH_BLOCKSIZE);
|
||||||
if( c->count == BLOWFISH_BLOCKSIZE ) {
|
if( c->count == BLOWFISH_BLOCKSIZE ) {
|
||||||
encrypted_block( c, c->eniv, c->iv );
|
encrypt_block( c, c->eniv, c->iv );
|
||||||
c->count = 0;
|
c->count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -461,7 +548,7 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf,
|
|||||||
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
|
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
|
||||||
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
|
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
|
||||||
memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE);
|
memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE);
|
||||||
encrypted_block( c, c->eniv, c->iv );
|
encrypt_block( c, c->eniv, c->iv );
|
||||||
nbytes -= BLOWFISH_BLOCKSIZE;
|
nbytes -= BLOWFISH_BLOCKSIZE;
|
||||||
inbuf += BLOWFISH_BLOCKSIZE;
|
inbuf += BLOWFISH_BLOCKSIZE;
|
||||||
outbuf += BLOWFISH_BLOCKSIZE;
|
outbuf += BLOWFISH_BLOCKSIZE;
|
||||||
@ -495,7 +582,7 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
|
|||||||
outbuf += n;
|
outbuf += n;
|
||||||
assert( c->count <= BLOWFISH_BLOCKSIZE);
|
assert( c->count <= BLOWFISH_BLOCKSIZE);
|
||||||
if( c->count == BLOWFISH_BLOCKSIZE ) {
|
if( c->count == BLOWFISH_BLOCKSIZE ) {
|
||||||
encrypted_block( c, c->eniv, c->iv );
|
encrypt_block( c, c->eniv, c->iv );
|
||||||
c->count = 0;
|
c->count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -506,7 +593,7 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
|
|||||||
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
|
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
|
||||||
memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE);
|
memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE);
|
||||||
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
|
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
|
||||||
encrypted_block( c, c->eniv, c->iv );
|
encrypt_block( c, c->eniv, c->iv );
|
||||||
nbytes -= BLOWFISH_BLOCKSIZE;
|
nbytes -= BLOWFISH_BLOCKSIZE;
|
||||||
inbuf += BLOWFISH_BLOCKSIZE;
|
inbuf += BLOWFISH_BLOCKSIZE;
|
||||||
outbuf += BLOWFISH_BLOCKSIZE;
|
outbuf += BLOWFISH_BLOCKSIZE;
|
||||||
|
@ -47,6 +47,12 @@
|
|||||||
* with RFC1113 !
|
* with RFC1113 !
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Test values:
|
||||||
|
* "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
|
||||||
|
* "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
|
||||||
|
* "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
|
||||||
|
* "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
|
||||||
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -156,7 +156,7 @@ initialize( RMDHANDLE hd )
|
|||||||
* Transform the message X which consists of 16 32-bit-words
|
* Transform the message X which consists of 16 32-bit-words
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
transform( RMDHANDLE hd, u32 *x )
|
transform( RMDHANDLE hd, byte *data )
|
||||||
{
|
{
|
||||||
static int r[80] = {
|
static int r[80] = {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
@ -184,6 +184,11 @@ transform( RMDHANDLE hd, u32 *x )
|
|||||||
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
|
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
|
||||||
u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
|
u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
|
||||||
int rbits, j;
|
int rbits, j;
|
||||||
|
#ifdef BIG_ENDIAN_HOST
|
||||||
|
u32 x[16];
|
||||||
|
#else
|
||||||
|
u32 *x;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define K(a) ( (a) < 16 ? 0x00000000 : \
|
#define K(a) ( (a) < 16 ? 0x00000000 : \
|
||||||
(a) < 32 ? 0x5A827999 : \
|
(a) < 32 ? 0x5A827999 : \
|
||||||
@ -207,6 +212,21 @@ transform( RMDHANDLE hd, u32 *x )
|
|||||||
|
|
||||||
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BIG_ENDIAN_HOST
|
||||||
|
{ int i;
|
||||||
|
byte *p2, *p1;
|
||||||
|
for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
|
||||||
|
p2[3] = *p1++;
|
||||||
|
p2[2] = *p1++;
|
||||||
|
p2[1] = *p1++;
|
||||||
|
p2[0] = *p1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
x = data;
|
||||||
|
#endif
|
||||||
|
|
||||||
a = aa = hd->h0;
|
a = aa = hd->h0;
|
||||||
b = bb = hd->h1;
|
b = bb = hd->h1;
|
||||||
c = cc = hd->h2;
|
c = cc = hd->h2;
|
||||||
@ -290,7 +310,7 @@ void
|
|||||||
rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
|
rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
|
||||||
{
|
{
|
||||||
if( hd->bufcount == 64 ) { /* flush the buffer */
|
if( hd->bufcount == 64 ) { /* flush the buffer */
|
||||||
transform( hd, (u32*)hd->buffer );
|
transform( hd, hd->buffer );
|
||||||
hd->bufcount = 0;
|
hd->bufcount = 0;
|
||||||
hd->nblocks++;
|
hd->nblocks++;
|
||||||
}
|
}
|
||||||
@ -305,7 +325,7 @@ rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while( inlen >= 64 ) {
|
while( inlen >= 64 ) {
|
||||||
transform( hd, (u32*)inbuf );
|
transform( hd, inbuf );
|
||||||
hd->bufcount = 0;
|
hd->bufcount = 0;
|
||||||
hd->nblocks++;
|
hd->nblocks++;
|
||||||
inlen -= 64;
|
inlen -= 64;
|
||||||
@ -365,12 +385,12 @@ rmd160_final(RMDHANDLE hd)
|
|||||||
hd->buffer[61] = msb >> 8;
|
hd->buffer[61] = msb >> 8;
|
||||||
hd->buffer[62] = msb >> 16;
|
hd->buffer[62] = msb >> 16;
|
||||||
hd->buffer[63] = msb >> 24;
|
hd->buffer[63] = msb >> 24;
|
||||||
transform( hd, (u32*)hd->buffer );
|
transform( hd, hd->buffer );
|
||||||
|
|
||||||
p = hd->buffer;
|
p = hd->buffer;
|
||||||
#ifdef BIG_ENDIAN_HOST
|
#ifdef BIG_ENDIAN_HOST
|
||||||
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
|
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
|
||||||
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
|
*p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
|
||||||
#else /* little endian */
|
#else /* little endian */
|
||||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||||
#endif
|
#endif
|
||||||
@ -386,3 +406,4 @@ rmd160_final(RMDHANDLE hd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,4 +397,3 @@ sha1_final(SHA1HANDLE hd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,12 +230,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
|
|||||||
mpi_write(a, skc->d.elg.p );
|
mpi_write(a, skc->d.elg.p );
|
||||||
mpi_write(a, skc->d.elg.g );
|
mpi_write(a, skc->d.elg.g );
|
||||||
mpi_write(a, skc->d.elg.y );
|
mpi_write(a, skc->d.elg.y );
|
||||||
iobuf_put(a, skc->d.elg.protect_algo );
|
if( skc->d.elg.is_protected ) {
|
||||||
if( skc->d.elg.protect_algo ) {
|
|
||||||
assert( skc->d.elg.is_protected == 1 );
|
|
||||||
assert( skc->d.elg.protect_algo == CIPHER_ALGO_BLOWFISH );
|
assert( skc->d.elg.protect_algo == CIPHER_ALGO_BLOWFISH );
|
||||||
|
iobuf_put(a, skc->d.elg.protect_algo );
|
||||||
iobuf_write(a, skc->d.elg.protect.blowfish.iv, 8 );
|
iobuf_write(a, skc->d.elg.protect.blowfish.iv, 8 );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
iobuf_put(a, 0 );
|
||||||
|
|
||||||
mpi_write(a, skc->d.elg.x );
|
mpi_write(a, skc->d.elg.x );
|
||||||
write_16(a, skc->d.elg.csum );
|
write_16(a, skc->d.elg.csum );
|
||||||
@ -243,12 +244,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
|
|||||||
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
mpi_write(a, skc->d.rsa.rsa_n );
|
mpi_write(a, skc->d.rsa.rsa_n );
|
||||||
mpi_write(a, skc->d.rsa.rsa_e );
|
mpi_write(a, skc->d.rsa.rsa_e );
|
||||||
iobuf_put(a, skc->d.rsa.protect_algo );
|
if( skc->d.rsa.is_protected ) {
|
||||||
if( skc->d.rsa.protect_algo ) {
|
|
||||||
assert( skc->d.rsa.is_protected == 1 );
|
|
||||||
assert( skc->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH );
|
assert( skc->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH );
|
||||||
|
iobuf_put(a, skc->d.rsa.protect_algo );
|
||||||
iobuf_write(a, skc->d.rsa.protect.blowfish.iv, 8 );
|
iobuf_write(a, skc->d.rsa.protect.blowfish.iv, 8 );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
iobuf_put(a, 0 );
|
||||||
mpi_write(a, skc->d.rsa.rsa_d );
|
mpi_write(a, skc->d.rsa.rsa_d );
|
||||||
mpi_write(a, skc->d.rsa.rsa_p );
|
mpi_write(a, skc->d.rsa.rsa_p );
|
||||||
mpi_write(a, skc->d.rsa.rsa_q );
|
mpi_write(a, skc->d.rsa.rsa_q );
|
||||||
|
14
g10/g10.c
14
g10/g10.c
@ -38,7 +38,7 @@
|
|||||||
enum cmd_values { aNull = 0,
|
enum cmd_values { aNull = 0,
|
||||||
aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||||
aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
|
aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
|
||||||
aKMode, aKModeC,
|
aKMode, aKModeC, aChangePass,
|
||||||
aTest };
|
aTest };
|
||||||
|
|
||||||
|
|
||||||
@ -158,7 +158,6 @@ main( int argc, char **argv )
|
|||||||
{ 512, "cache-all" ,0, "hold everything in memory"},
|
{ 512, "cache-all" ,0, "hold everything in memory"},
|
||||||
{ 513, "gen-prime" , 0, "\r" },
|
{ 513, "gen-prime" , 0, "\r" },
|
||||||
{ 514, "test" , 0, "\r" },
|
{ 514, "test" , 0, "\r" },
|
||||||
{ 515, "change-passphrase", 0, "change the passphrase of your secret keyring"},
|
|
||||||
{ 515, "fingerprint", 0, "show the fingerprints"},
|
{ 515, "fingerprint", 0, "show the fingerprints"},
|
||||||
{ 516, "print-mds" , 0, "print all message digests"},
|
{ 516, "print-mds" , 0, "print all message digests"},
|
||||||
{ 517, "secret-keyring" ,2, "add this secret keyring to the list" },
|
{ 517, "secret-keyring" ,2, "add this secret keyring to the list" },
|
||||||
@ -169,6 +168,7 @@ main( int argc, char **argv )
|
|||||||
{ 522, "no-greeting", 0, "\r" },
|
{ 522, "no-greeting", 0, "\r" },
|
||||||
{ 523, "passphrase-fd",1, "\r" },
|
{ 523, "passphrase-fd",1, "\r" },
|
||||||
{ 524, "edit-sig" ,0, "edit a key signature" },
|
{ 524, "edit-sig" ,0, "edit a key signature" },
|
||||||
|
{ 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
|
||||||
|
|
||||||
{0} };
|
{0} };
|
||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
@ -297,6 +297,7 @@ main( int argc, char **argv )
|
|||||||
case 522: greeting = 0; break;
|
case 522: greeting = 0; break;
|
||||||
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
||||||
case 524: set_cmd( &cmd, aEditSig); break;
|
case 524: set_cmd( &cmd, aEditSig); break;
|
||||||
|
case 525: set_cmd( &cmd, aChangePass); break;
|
||||||
default : errors++; pargs.err = configfp? 1:2; break;
|
default : errors++; pargs.err = configfp? 1:2; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -406,6 +407,15 @@ main( int argc, char **argv )
|
|||||||
log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
|
log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aChangePass: /* Chnage the passphrase */
|
||||||
|
if( argc > 1 ) /* no arg: use default, 1 arg use this one */
|
||||||
|
usage(1);
|
||||||
|
/* note: fname is the user id! */
|
||||||
|
if( (rc = change_passphrase(fname)) )
|
||||||
|
log_error("change_passphrase('%s'): %s\n", fname_print,
|
||||||
|
g10_errstr(rc) );
|
||||||
|
break;
|
||||||
|
|
||||||
case aKMode: /* list keyring */
|
case aKMode: /* list keyring */
|
||||||
if( !argc ) { /* list the default public keyrings */
|
if( !argc ) { /* list the default public keyrings */
|
||||||
int i, seq=0;
|
int i, seq=0;
|
||||||
|
10
g10/getkey.c
10
g10/getkey.c
@ -83,7 +83,7 @@ add_keyring( const char *name )
|
|||||||
* combine it with the keyblock stuff from ringedit.c
|
* combine it with the keyblock stuff from ringedit.c
|
||||||
* For now we will simple add the filename as keyblock resource
|
* For now we will simple add the filename as keyblock resource
|
||||||
*/
|
*/
|
||||||
rc = add_keyblock_resource( name, 0 );
|
rc = add_keyblock_resource( name, 0, 0 );
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error("keyblock resource '%s': %s\n", name, g10_errstr(rc) );
|
log_error("keyblock resource '%s': %s\n", name, g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
@ -115,6 +115,14 @@ add_secret_keyring( const char *name )
|
|||||||
strcpy(sl->d, name );
|
strcpy(sl->d, name );
|
||||||
sl->next = secret_keyrings;
|
sl->next = secret_keyrings;
|
||||||
secret_keyrings = sl;
|
secret_keyrings = sl;
|
||||||
|
|
||||||
|
/* FIXME: We should remove much out of this mpdule and
|
||||||
|
* combine it with the keyblock stuff from ringedit.c
|
||||||
|
* For now we will simple add the filename as keyblock resource
|
||||||
|
*/
|
||||||
|
rc = add_keyblock_resource( name, 0, 1 );
|
||||||
|
if( rc )
|
||||||
|
log_error("secret keyblock resource '%s': %s\n", name, g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,10 +125,11 @@ KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
|
|||||||
void clear_kbnode_flags( KBNODE n );
|
void clear_kbnode_flags( KBNODE n );
|
||||||
|
|
||||||
/*-- ringedit.c --*/
|
/*-- ringedit.c --*/
|
||||||
int add_keyblock_resource( const char *filename, int force );
|
int add_keyblock_resource( const char *filename, int force, int secret );
|
||||||
int get_keyblock_handle( const char *filename, KBPOS *kbpos );
|
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||||
int search_keyblock( PACKET *pkt, KBPOS *kbpos );
|
int search_keyblock( PACKET *pkt, KBPOS *kbpos, int secret );
|
||||||
int search_keyblock_byname( KBPOS *kbpos, const char *username );
|
int search_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||||
|
int search_secret_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||||
int lock_keyblock( KBPOS *kbpos );
|
int lock_keyblock( KBPOS *kbpos );
|
||||||
void unlock_keyblock( KBPOS *kbpos );
|
void unlock_keyblock( KBPOS *kbpos );
|
||||||
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
|
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
|
||||||
|
12
g10/keygen.c
12
g10/keygen.c
@ -507,24 +507,24 @@ generate_keypair()
|
|||||||
/* we can now write the certificates */
|
/* we can now write the certificates */
|
||||||
/* FIXME: should we check wether the user-id already exists? */
|
/* FIXME: should we check wether the user-id already exists? */
|
||||||
|
|
||||||
if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
|
if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
|
||||||
if( add_keyblock_resource( pub_fname, 1 ) ) {
|
if( add_keyblock_resource( pub_fname, 1, 0 ) ) {
|
||||||
log_error("can add keyblock file '%s'\n", pub_fname );
|
log_error("can add keyblock file '%s'\n", pub_fname );
|
||||||
rc = G10ERR_CREATE_FILE;
|
rc = G10ERR_CREATE_FILE;
|
||||||
}
|
}
|
||||||
else if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
|
else if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
|
||||||
log_error("can get keyblock handle for '%s'\n", pub_fname );
|
log_error("can get keyblock handle for '%s'\n", pub_fname );
|
||||||
rc = G10ERR_CREATE_FILE;
|
rc = G10ERR_CREATE_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc )
|
if( rc )
|
||||||
;
|
;
|
||||||
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
|
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
|
||||||
if( add_keyblock_resource( sec_fname, 1 ) ) {
|
if( add_keyblock_resource( sec_fname, 1, 1 ) ) {
|
||||||
log_error("can add keyblock file '%s'\n", sec_fname );
|
log_error("can add keyblock file '%s'\n", sec_fname );
|
||||||
rc = G10ERR_CREATE_FILE;
|
rc = G10ERR_CREATE_FILE;
|
||||||
}
|
}
|
||||||
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
|
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
|
||||||
log_error("can get keyblock handle for '%s'\n", sec_fname );
|
log_error("can get keyblock handle for '%s'\n", sec_fname );
|
||||||
rc = G10ERR_CREATE_FILE;
|
rc = G10ERR_CREATE_FILE;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ int sign_file( const char *filename, int detached, STRLIST locusr,
|
|||||||
int encrypt, STRLIST remusr );
|
int encrypt, STRLIST remusr );
|
||||||
int sign_key( const char *username, STRLIST locusr );
|
int sign_key( const char *username, STRLIST locusr );
|
||||||
int edit_keysigs( const char *username );
|
int edit_keysigs( const char *username );
|
||||||
|
int change_passphrase( const char *username );
|
||||||
|
|
||||||
/*-- sig-check.c --*/
|
/*-- sig-check.c --*/
|
||||||
int check_key_signature( KBNODE root, KBNODE node );
|
int check_key_signature( KBNODE root, KBNODE node );
|
||||||
|
@ -238,6 +238,7 @@ PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s );
|
|||||||
int signature_check( PKT_signature *sig, MD_HANDLE *digest );
|
int signature_check( PKT_signature *sig, MD_HANDLE *digest );
|
||||||
|
|
||||||
/*-- seckey-cert.c --*/
|
/*-- seckey-cert.c --*/
|
||||||
|
int is_secret_key_protected( PKT_secret_cert *cert );
|
||||||
int check_secret_key( PKT_secret_cert *cert );
|
int check_secret_key( PKT_secret_cert *cert );
|
||||||
int protect_secret_key( PKT_secret_cert *cert, DEK *dek );
|
int protect_secret_key( PKT_secret_cert *cert, DEK *dek );
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
struct resource_table_struct {
|
struct resource_table_struct {
|
||||||
int used;
|
int used;
|
||||||
|
int secret; /* this is a secret keyring */
|
||||||
char *fname;
|
char *fname;
|
||||||
IOBUF iobuf;
|
IOBUF iobuf;
|
||||||
};
|
};
|
||||||
@ -94,7 +95,7 @@ check_pos( KBPOS *kbpos )
|
|||||||
* Register a resource (which currently may ionly be a keyring file).
|
* Register a resource (which currently may ionly be a keyring file).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
add_keyblock_resource( const char *filename, int force )
|
add_keyblock_resource( const char *filename, int force, int secret )
|
||||||
{
|
{
|
||||||
IOBUF iobuf;
|
IOBUF iobuf;
|
||||||
int i;
|
int i;
|
||||||
@ -109,6 +110,7 @@ add_keyblock_resource( const char *filename, int force )
|
|||||||
if( !iobuf && !force )
|
if( !iobuf && !force )
|
||||||
return G10ERR_OPEN_FILE;
|
return G10ERR_OPEN_FILE;
|
||||||
resource_table[i].used = 1;
|
resource_table[i].used = 1;
|
||||||
|
resource_table[i].secret = !!secret;
|
||||||
resource_table[i].fname = m_strdup(filename);
|
resource_table[i].fname = m_strdup(filename);
|
||||||
resource_table[i].iobuf = iobuf;
|
resource_table[i].iobuf = iobuf;
|
||||||
return 0;
|
return 0;
|
||||||
@ -120,12 +122,12 @@ add_keyblock_resource( const char *filename, int force )
|
|||||||
* to get a handle for insert_keyblock for a new keyblock.
|
* to get a handle for insert_keyblock for a new keyblock.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
get_keyblock_handle( const char *filename, KBPOS *kbpos )
|
get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0; i < MAX_RESOURCES; i++ )
|
for(i=0; i < MAX_RESOURCES; i++ )
|
||||||
if( resource_table[i].used ) {
|
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
|
||||||
/* fixme: dos needs case insensitive file compare */
|
/* fixme: dos needs case insensitive file compare */
|
||||||
if( !strcmp( resource_table[i].fname, filename ) ) {
|
if( !strcmp( resource_table[i].fname, filename ) ) {
|
||||||
memset( kbpos, 0, sizeof *kbpos );
|
memset( kbpos, 0, sizeof *kbpos );
|
||||||
@ -148,12 +150,12 @@ get_keyblock_handle( const char *filename, KBPOS *kbpos )
|
|||||||
* Returns: 0 if found, -1 if not found or an errorcode.
|
* Returns: 0 if found, -1 if not found or an errorcode.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
search_keyblock( PACKET *pkt, KBPOS *kbpos )
|
search_keyblock( PACKET *pkt, KBPOS *kbpos, int secret )
|
||||||
{
|
{
|
||||||
int i, rc, last_rc=-1;
|
int i, rc, last_rc=-1;
|
||||||
|
|
||||||
for(i=0; i < MAX_RESOURCES; i++ ) {
|
for(i=0; i < MAX_RESOURCES; i++ ) {
|
||||||
if( resource_table[i].used ) {
|
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
|
||||||
/* note: here we have to add different search functions,
|
/* note: here we have to add different search functions,
|
||||||
* depending on the type of the resource */
|
* depending on the type of the resource */
|
||||||
rc = keyring_search( pkt, kbpos, resource_table[i].iobuf );
|
rc = keyring_search( pkt, kbpos, resource_table[i].iobuf );
|
||||||
@ -192,11 +194,36 @@ search_keyblock_byname( KBPOS *kbpos, const char *username )
|
|||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
pkt.pkttype = PKT_PUBLIC_CERT;
|
pkt.pkttype = PKT_PUBLIC_CERT;
|
||||||
pkt.pkt.public_cert = pkc;
|
pkt.pkt.public_cert = pkc;
|
||||||
rc = search_keyblock( &pkt, kbpos );
|
rc = search_keyblock( &pkt, kbpos, 0 );
|
||||||
free_public_cert(pkc);
|
free_public_cert(pkc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Combined function to search for a username and get the position
|
||||||
|
* of the keyblock. This function does not unprotect the secret key.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
search_secret_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||||
|
{
|
||||||
|
PACKET pkt;
|
||||||
|
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = get_seckey_byname( skc, username, 0 );
|
||||||
|
if( rc ) {
|
||||||
|
free_secret_cert(skc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_packet( &pkt );
|
||||||
|
pkt.pkttype = PKT_SECRET_CERT;
|
||||||
|
pkt.pkt.secret_cert = skc;
|
||||||
|
rc = search_keyblock( &pkt, kbpos, 1 );
|
||||||
|
free_secret_cert(skc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Lock the keyblock; wait until it's available
|
* Lock the keyblock; wait until it's available
|
||||||
|
@ -284,6 +284,23 @@ check_secret_key( PKT_secret_cert *cert )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* check wether the secret key is protected.
|
||||||
|
* Returns: 0 not protected, -1 on error or the protection algorithm
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
is_secret_key_protected( PKT_secret_cert *cert )
|
||||||
|
{
|
||||||
|
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||||
|
return cert->d.elg.is_protected? cert->d.elg.protect_algo : 0;
|
||||||
|
#ifdef HAVE_RSA_CIPHER
|
||||||
|
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||||
|
return cert->d.rsa.is_protected? cert->d.rsa.protect_algo : 0;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return -1; /* unsupported */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Protect the secret key certificate with the passphrase from DEK
|
* Protect the secret key certificate with the passphrase from DEK
|
||||||
|
123
g10/sign.c
123
g10/sign.c
@ -695,6 +695,129 @@ edit_keysigs( const char *username )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
change_passphrase( const char *username )
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
KBNODE keyblock = NULL;
|
||||||
|
KBNODE kbctx, node;
|
||||||
|
KBPOS kbpos;
|
||||||
|
PKT_secret_cert *skc;
|
||||||
|
int any;
|
||||||
|
u32 skc_keyid[2];
|
||||||
|
char *answer;
|
||||||
|
int changed=0;
|
||||||
|
|
||||||
|
/* search the userid */
|
||||||
|
rc = search_secret_keyblock_byname( &kbpos, username );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("secret key for user '%s' not found\n", username );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the keyblock */
|
||||||
|
rc = read_keyblock( &kbpos, &keyblock );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("error reading the certificate: %s\n", g10_errstr(rc) );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the keyid from the keyblock */
|
||||||
|
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
|
||||||
|
if( node->pkt->pkttype == PKT_SECRET_CERT )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( !node ) {
|
||||||
|
log_error("Oops; secret key not found anymore!\n");
|
||||||
|
rc = G10ERR_GENERAL;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
skc = node->pkt->pkt.secret_cert;
|
||||||
|
keyid_from_skc( skc, skc_keyid );
|
||||||
|
tty_printf("sec %4u%c/%08lX %s ",
|
||||||
|
nbits_from_skc( skc ),
|
||||||
|
pubkey_letter( skc->pubkey_algo ),
|
||||||
|
skc_keyid[1], datestr_from_skc(skc) );
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
char *p = get_user_id( skc_keyid, &n );
|
||||||
|
tty_print_string( p, n );
|
||||||
|
m_free(p);
|
||||||
|
tty_printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_kbnode_flags( keyblock );
|
||||||
|
switch( is_secret_key_protected( skc ) ) {
|
||||||
|
case -1:
|
||||||
|
rc = G10ERR_PUBKEY_ALGO;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
tty_printf("This key is not protected.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tty_printf("Key is protected.\n");
|
||||||
|
rc = check_secret_key( skc );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc )
|
||||||
|
tty_printf("Can't edit this key: %s\n", g10_errstr(rc));
|
||||||
|
else {
|
||||||
|
DEK *dek = m_alloc_secure( sizeof *dek );
|
||||||
|
|
||||||
|
tty_printf( "Enter the new passphrase for this secret key.\n\n" );
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
dek->algo = CIPHER_ALGO_BLOWFISH;
|
||||||
|
rc = make_dek_from_passphrase( dek , 2 );
|
||||||
|
if( rc == -1 ) {
|
||||||
|
rc = 0;
|
||||||
|
tty_printf( "You don't want a passphrase -"
|
||||||
|
" this is probably a *bad* idea!\n\n");
|
||||||
|
answer = tty_get("Do you really want to do this? ");
|
||||||
|
tty_kill_prompt();
|
||||||
|
if( answer_is_yes(answer) )
|
||||||
|
changed++;
|
||||||
|
m_free(answer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( rc == G10ERR_PASSPHRASE ) {
|
||||||
|
tty_printf("passphrase not correctly repeated; try again.\n");
|
||||||
|
}
|
||||||
|
else if( rc ) {
|
||||||
|
m_free(dek); dek = NULL;
|
||||||
|
log_error("Error getting the passphrase: %s\n", g10_errstr(rc));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else { /* okay */
|
||||||
|
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
|
||||||
|
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
|
||||||
|
rc = protect_secret_key( skc, dek );
|
||||||
|
if( rc )
|
||||||
|
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
|
||||||
|
else
|
||||||
|
changed++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_free(dek);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( changed ) {
|
||||||
|
rc = update_keyblock( &kbpos, keyblock );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
release_kbnode( keyblock );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Create a signature packet for the given public key certificate
|
* Create a signature packet for the given public key certificate
|
||||||
|
@ -58,7 +58,7 @@ case "${target}" in
|
|||||||
*-*-linuxaout* | *-*-linuxoldld*)
|
*-*-linuxaout* | *-*-linuxoldld*)
|
||||||
needs_underscore="y"
|
needs_underscore="y"
|
||||||
;;
|
;;
|
||||||
*-*-linux* | *-sysv* | *-solaris*)
|
*-*-linux* | *-sysv* | *-solaris* | *-gnu*)
|
||||||
needs_underscore="n"
|
needs_underscore="n"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user