diff options
Diffstat (limited to 'g10/keyid.c')
-rw-r--r-- | g10/keyid.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/g10/keyid.c b/g10/keyid.c index 7453754a2..e3a16d86b 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -171,3 +171,110 @@ datestr_from_sig( PKT_signature *sig ) return buffer; } + +/**************** . + * Return a byte array with the fingerprint for the given PKC/SKC + * 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; + if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { + 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_RSA ) { + pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n; + pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e; + } + p = fingerprint_from_pkc( &pkc, ret_len ); + memset(&pkc, 0, sizeof pkc); /* not really needed */ + return p; +} + +byte * +fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ) +{ + byte *p, *buf, *array; + size_t len; + unsigned n; + + if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { + RMDHANDLE md; + const char *dp; + + md = rmd160_open(0); + + { u32 a = pkc->timestamp; + rmd160_putchar( md, a >> 24 ); + rmd160_putchar( md, a >> 16 ); + rmd160_putchar( md, a >> 8 ); + rmd160_putchar( md, a ); + } + { u16 a = pkc->valid_days; + rmd160_putchar( md, a >> 8 ); + rmd160_putchar( md, a ); + } + rmd160_putchar( md, pkc->pubkey_algo ); + p = buf = mpi_get_buffer( pkc->d.elg.p, &n, NULL ); + for( ; !*p && n; p++, n-- ) + ; + rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( pkc->d.elg.g, &n, NULL ); + for( ; !*p && n; p++, n-- ) + ; + rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( pkc->d.elg.y, &n, NULL ); + for( ; !*p && n; p++, n-- ) + ; + rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n ); + m_free(buf); + + dp = rmd160_final(md); + array = m_alloc( 20 ); + len = 20; + memcpy(array, dp, 20 ); + rmd160_close(md); + } + else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { + MD5HANDLE md; + + md = md5_open(0); + p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL ); + for( ; !*p && n; p++, n-- ) + ; + md5_write( md, p, n ); + m_free(buf); + p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL ); + for( ; !*p && n; p++, n-- ) + ; + md5_write( md, p, n ); + m_free(buf); + md5_final(md); + array = m_alloc( 16 ); + len = 16; + memcpy(array, md5_read(md), 16 ); + md5_close(md); + } + else { + array = m_alloc(1); + len = 0; /* ooops */ + } + + *ret_len = len; + return array; +} + + + |