diff options
Diffstat (limited to 'g10/keyid.c')
-rw-r--r-- | g10/keyid.c | 355 |
1 files changed, 89 insertions, 266 deletions
diff --git a/g10/keyid.c b/g10/keyid.c index 55c0c49ae..dc24904c7 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -47,182 +47,72 @@ pubkey_letter( int algo ) } } -/* this is special code for V3 which uses ElGamal and - * calculates a fingerprint like V4, but with rmd160 - * and a version byte of 3. Returns an md handle, caller must - * do md_close() - */ static MD_HANDLE -v3_elg_fingerprint_md( PKT_public_cert *pkc ) +do_fingerprint_md( PKT_public_cert *pkc ) { MD_HANDLE md; - byte *buf1, *buf2, *buf3; - byte *p1, *p2, *p3; - unsigned n1, n2, n3; - unsigned nb1, nb2, nb3; unsigned n; - - nb1 = mpi_get_nbits(pkc->d.elg.p); - p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL ); - nb2 = mpi_get_nbits(pkc->d.elg.g); - p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL ); - nb3 = mpi_get_nbits(pkc->d.elg.y); - p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL ); - - /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */ - n = 14 + n1 + n2 + n3; - md = md_open( DIGEST_ALGO_RMD160, 0); + unsigned nb[PUBKEY_MAX_NPKEY]; + unsigned nn[PUBKEY_MAX_NPKEY]; + byte *pp[PUBKEY_MAX_NPKEY]; + int i; + int npkey = pubkey_get_npkey( pkc->pubkey_algo ); + + md = md_open( pkc->version < 4 ? DIGEST_ALGO_RMD160 : DIGEST_ALGO_SHA1, 0); + n = pkc->version < 4 ? 8 : 6; + for(i=0; i < npkey; i++ ) { + nb[i] = mpi_get_nbits(pkc->pkey[i]); + pp[i] = mpi_get_buffer( pkc->pkey[i], nn+i, NULL ); + n += 2 + nn[i]; + } md_putc( md, 0x99 ); /* ctb */ md_putc( md, n >> 8 ); /* 2 byte length header */ md_putc( md, n ); - md_putc( md, 3 ); /* version */ + if( pkc->version < 4 ) + md_putc( md, 3 ); + else + md_putc( md, 4 ); + { u32 a = pkc->timestamp; md_putc( md, a >> 24 ); md_putc( md, a >> 16 ); md_putc( md, a >> 8 ); md_putc( md, a ); } - { u16 a = pkc->valid_days; + if( pkc->version < 4 ) { + u16 a = pkc->valid_days; md_putc( md, a >> 8 ); md_putc( md, a ); } md_putc( md, pkc->pubkey_algo ); - md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 ); - md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 ); - md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 ); - m_free(buf1); - m_free(buf2); - m_free(buf3); - md_final( md ); - - return md; -} - -static MD_HANDLE -elg_fingerprint_md( PKT_public_cert *pkc ) -{ - MD_HANDLE md; - byte *buf1, *buf3, *buf4 ; - byte *p1, *p3, *p4; - unsigned n1, n3, n4; - unsigned nb1, nb3, nb4; - unsigned n; - - nb1 = mpi_get_nbits(pkc->d.elg.p); - p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL ); - nb3 = mpi_get_nbits(pkc->d.elg.g); - p3 = buf3 = mpi_get_buffer( pkc->d.elg.g, &n3, NULL ); - nb4 = mpi_get_nbits(pkc->d.elg.y); - p4 = buf4 = mpi_get_buffer( pkc->d.elg.y, &n4, NULL ); - - /* calculate length of packet */ - n = 12 + n1 + n3 +n4 ; - md = md_open( DIGEST_ALGO_SHA1, 0); - - md_putc( md, 0x99 ); /* ctb */ - md_putc( md, n >> 8 ); /* 2 byte length header */ - md_putc( md, n ); - md_putc( md, 4 ); /* version */ - { u32 a = pkc->timestamp; - md_putc( md, a >> 24 ); - md_putc( md, a >> 16 ); - md_putc( md, a >> 8 ); - md_putc( md, a ); - } - md_putc( md, pkc->pubkey_algo ); - md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 ); - md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 ); - md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 ); - m_free(buf1); - m_free(buf3); - m_free(buf4); - md_final( md ); - - return md; -} - - -static MD_HANDLE -dsa_fingerprint_md( PKT_public_cert *pkc ) -{ - MD_HANDLE md; - byte *buf1, *buf2, *buf3, *buf4 ; - byte *p1, *p2, *p3, *p4; - unsigned n1, n2, n3, n4; - unsigned nb1, nb2, nb3, nb4; - unsigned n; - - nb1 = mpi_get_nbits(pkc->d.dsa.p); - p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL ); - nb2 = mpi_get_nbits(pkc->d.dsa.q); - p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL ); - nb3 = mpi_get_nbits(pkc->d.dsa.g); - p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL ); - nb4 = mpi_get_nbits(pkc->d.dsa.y); - p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL ); - - /* calculate length of packet */ - n = 14 + n1 + n2 + n3 +n4 ; - md = md_open( DIGEST_ALGO_SHA1, 0); - - md_putc( md, 0x99 ); /* ctb */ - md_putc( md, n >> 8 ); /* 2 byte length header */ - md_putc( md, n ); - md_putc( md, 4 ); /* version */ - { u32 a = pkc->timestamp; - md_putc( md, a >> 24 ); - md_putc( md, a >> 16 ); - md_putc( md, a >> 8 ); - md_putc( md, a ); + for(i=0; i < npkey; i++ ) { + md_putc( md, nb[i]>>8); + md_putc( md, nb[i] ); + md_write( md, pp[i], nn[i] ); + m_free(pp[i]); } - md_putc( md, pkc->pubkey_algo ); - md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 ); - md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 ); - md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 ); - md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 ); - m_free(buf1); - m_free(buf2); - m_free(buf3); - m_free(buf4); md_final( md ); return md; } static MD_HANDLE -elg_fingerprint_md_skc( PKT_secret_cert *skc ) +do_fingerprint_md_skc( PKT_secret_cert *skc ) { PKT_public_cert pkc; + int npkey = pubkey_get_npkey( skc->pubkey_algo ); /* npkey is correct! */ + int i; pkc.pubkey_algo = skc->pubkey_algo; pkc.version = skc->version; pkc.timestamp = skc->timestamp; pkc.valid_days = skc->valid_days; pkc.pubkey_algo = skc->pubkey_algo; - pkc.d.elg.p = skc->d.elg.p; - pkc.d.elg.g = skc->d.elg.g; - pkc.d.elg.y = skc->d.elg.y; - if( pkc.version < 4 ) - return v3_elg_fingerprint_md( &pkc ); - else - return elg_fingerprint_md( &pkc ); -} - -static MD_HANDLE -dsa_fingerprint_md_skc( PKT_secret_cert *skc ) -{ - PKT_public_cert pkc; - - pkc.pubkey_algo = skc->pubkey_algo; - pkc.timestamp = skc->timestamp; - pkc.pubkey_algo = skc->pubkey_algo; - pkc.d.dsa.p = skc->d.dsa.p; - pkc.d.dsa.q = skc->d.dsa.q; - pkc.d.dsa.g = skc->d.dsa.g; - pkc.d.dsa.y = skc->d.dsa.y; - return dsa_fingerprint_md( &pkc ); + for( i=0; i < npkey; i++ ) + pkc.pkey[i] = skc->skey[i]; + return do_fingerprint_md( &pkc ); } @@ -239,35 +129,20 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid ) if( !keyid ) keyid = dummy_keyid; - if( is_ELGAMAL(skc->pubkey_algo) ) { - const byte *dp; - MD_HANDLE md; - md = elg_fingerprint_md_skc(skc); - if( skc->version < 4 ) - dp = md_read( md, DIGEST_ALGO_RMD160 ); - else - dp = md_read( md, DIGEST_ALGO_SHA1 ); - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - md_close(md); + if( skc->version < 4 && is_RSA(skc->pubkey_algo) ) { + lowbits = mpi_get_keyid( skc->skey[0], keyid ); /* take n */ } - else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) { + else { const byte *dp; MD_HANDLE md; - md = dsa_fingerprint_md_skc(skc); - dp = md_read( md, DIGEST_ALGO_SHA1 ); + md = do_fingerprint_md_skc(skc); + dp = md_read( md, 0 ); keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; lowbits = keyid[1]; md_close(md); } - else if( is_RSA(skc->pubkey_algo) ) { - lowbits = mpi_get_keyid( skc->d.rsa.n, keyid ); - } - else { - keyid[0] = keyid[1] = lowbits = 0; - } + return lowbits; } @@ -285,38 +160,19 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid ) if( !keyid ) keyid = dummy_keyid; - if( is_ELGAMAL(pkc->pubkey_algo) ) { - const byte *dp; - MD_HANDLE md; - if( pkc->version < 4 ) { - md = v3_elg_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_RMD160 ); - } - else { - md = elg_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_SHA1 ); - } - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - md_close(md); + if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) { + lowbits = mpi_get_keyid( pkc->pkey[0], keyid ); /* from n */ } - else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) { + else { const byte *dp; MD_HANDLE md; - md = dsa_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_SHA1 ); + md = do_fingerprint_md(pkc); + dp = md_read( md, 0 ); keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; lowbits = keyid[1]; md_close(md); } - else if( is_RSA(pkc->pubkey_algo) ) { - lowbits = mpi_get_keyid( pkc->d.rsa.n, keyid ); - } - else { - keyid[0] = keyid[1] = lowbits = 0; - } return lowbits; } @@ -338,17 +194,7 @@ keyid_from_sig( PKT_signature *sig, u32 *keyid ) unsigned nbits_from_pkc( PKT_public_cert *pkc ) { - if( is_ELGAMAL(pkc->pubkey_algo) ) { - return mpi_get_nbits( pkc->d.elg.p ); - } - else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) { - return mpi_get_nbits( pkc->d.dsa.p ); - } - else if( is_RSA(pkc->pubkey_algo) ) { - return mpi_get_nbits( pkc->d.rsa.n ); - } - else - return 0; + return pubkey_nbits( pkc->pubkey_algo, pkc->pkey ); } /**************** @@ -357,17 +203,7 @@ nbits_from_pkc( PKT_public_cert *pkc ) unsigned nbits_from_skc( PKT_secret_cert *skc ) { - if( is_ELGAMAL(skc->pubkey_algo) ) { - return mpi_get_nbits( skc->d.elg.p ); - } - else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) { - return mpi_get_nbits( skc->d.dsa.p ); - } - else if( is_RSA(skc->pubkey_algo) ) { - return mpi_get_nbits( skc->d.rsa.n ); - } - else - return 0; + return pubkey_nbits( skc->pubkey_algo, skc->skey ); } /**************** @@ -417,40 +253,6 @@ datestr_from_sig( PKT_signature *sig ) * The length of the array is returned in ret_len. Caller must free * the array. */ -byte * -fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len ) -{ - PKT_public_cert pkc; - byte *p; - - pkc.pubkey_algo = skc->pubkey_algo; - pkc.version = skc->version; - if( is_ELGAMAL(pkc.pubkey_algo) ) { - pkc.timestamp = skc->timestamp; - pkc.valid_days = skc->valid_days; - pkc.pubkey_algo = skc->pubkey_algo; - pkc.d.elg.p = skc->d.elg.p; - pkc.d.elg.g = skc->d.elg.g; - pkc.d.elg.y = skc->d.elg.y; - } - else if( pkc.pubkey_algo == PUBKEY_ALGO_DSA ) { - pkc.timestamp = skc->timestamp; - pkc.valid_days = skc->valid_days; - pkc.pubkey_algo = skc->pubkey_algo; - pkc.d.dsa.p = skc->d.dsa.p; - pkc.d.dsa.q = skc->d.dsa.q; - pkc.d.dsa.g = skc->d.dsa.g; - pkc.d.dsa.y = skc->d.dsa.y; - } - else if( is_RSA(pkc.pubkey_algo) ) { - pkc.d.rsa.n = skc->d.rsa.n; - pkc.d.rsa.e = skc->d.rsa.e; - } - p = fingerprint_from_pkc( &pkc, ret_len ); - memset(&pkc, 0, sizeof pkc); /* not really needed */ - return p; -} - @@ -462,38 +264,54 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ) size_t len; unsigned n; - if( is_ELGAMAL(pkc->pubkey_algo) ) { + if( pkc->version < 4 && is_RSA(pkc->pubkey_algo) ) { + /* RSA in version 3 packets is special */ MD_HANDLE md; - if( pkc->version < 4 ) { - md = v3_elg_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_RMD160 ); - } - else { - md = elg_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_SHA1 ); - } - array = m_alloc( 20 ); - len = 20; - memcpy(array, dp, 20 ); + + md = md_open( DIGEST_ALGO_MD5, 0); + p = buf = mpi_get_buffer( pkc->pkey[0], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( pkc->pkey[1], &n, NULL ); + md_write( md, p, n ); + m_free(buf); + md_final(md); + array = m_alloc( 16 ); + len = 16; + memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 ); md_close(md); } - else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) { + else { MD_HANDLE md; - md = dsa_fingerprint_md(pkc); - dp = md_read( md, DIGEST_ALGO_SHA1 ); - array = m_alloc( 20 ); - len = 20; - memcpy(array, dp, 20 ); + md = do_fingerprint_md(pkc); + dp = md_read( md, 0 ); + len = md_digest_length( md_get_algo( md ) ); + array = m_alloc( len ); + memcpy(array, dp, len ); md_close(md); } - else if( is_RSA(pkc->pubkey_algo) ) { + + *ret_len = len; + return array; +} + +byte * +fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len ) +{ + byte *p, *buf, *array; + const char *dp; + size_t len; + unsigned n; + + if( skc->version < 4 && is_RSA(skc->pubkey_algo) ) { + /* RSA in version 3 packets is special */ MD_HANDLE md; md = md_open( DIGEST_ALGO_MD5, 0); - p = buf = mpi_get_buffer( pkc->d.rsa.n, &n, NULL ); + p = buf = mpi_get_buffer( skc->skey[1], &n, NULL ); md_write( md, p, n ); m_free(buf); - p = buf = mpi_get_buffer( pkc->d.rsa.e, &n, NULL ); + p = buf = mpi_get_buffer( skc->skey[0], &n, NULL ); md_write( md, p, n ); m_free(buf); md_final(md); @@ -503,8 +321,13 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ) md_close(md); } else { - array = m_alloc(1); - len = 0; /* ooops */ + MD_HANDLE md; + md = do_fingerprint_md_skc(skc); + dp = md_read( md, 0 ); + len = md_digest_length( md_get_algo( md ) ); + array = m_alloc( len ); + memcpy(array, dp, len ); + md_close(md); } *ret_len = len; |