Trust stuff works partly.
[gnupg.git] / g10 / keyid.c
index 307e28c..5d5a043 100644 (file)
@@ -46,6 +46,77 @@ 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 )
+{
+    MD_HANDLE md;
+    byte *buf1, *buf2, *buf3;
+    byte *p1, *p2, *p3;
+    unsigned n1, n2, n3;
+    unsigned n;
+
+    p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
+    for( ; !*p1 && n1; p1++, n1-- )  /* skip leading null bytes */
+       ;
+    p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
+    for( ; !*p2 && n2; p2++, n2-- )  /* skip leading null bytes */
+       ;
+    p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
+    for( ; !*p3 && n3; p3++, n3-- )  /* skip leading null bytes */
+       ;
+
+    /* 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);
+
+    md_putc( md, 0x99 );     /* ctb */
+    md_putc( md, n >> 8 );   /* 2 byte length header */
+    md_putc( md, n );
+    md_putc( md, 3 );       /* version */
+    {  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;
+       md_putc( md, a >> 8 );
+       md_putc( md, a      );
+    }
+    md_putc( md, pkc->pubkey_algo );
+    md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
+    md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
+    md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
+    m_free(buf1);
+    m_free(buf2);
+    m_free(buf3);
+    md_final( md );
+
+    return md;
+}
+
+
+static MD_HANDLE
+v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
+{
+    PKT_public_cert pkc;
+
+    pkc.pubkey_algo = skc->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;
+    return v3_elg_fingerprint_md( &pkc );
+}
+
 
 /****************
  * Get the keyid from the secret key certificate and put it into keyid
@@ -61,7 +132,14 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
        keyid = dummy_keyid;
 
     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       lowbits = mpi_get_keyid( skc->d.elg.y, keyid );
+       const byte *dp;
+       MD_HANDLE md;
+       md = v3_elg_fingerprint_md_skc(skc);
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
+       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( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
        lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
@@ -87,7 +165,14 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
        keyid = dummy_keyid;
 
     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       lowbits = mpi_get_keyid( pkc->d.elg.y, keyid );
+       const byte *dp;
+       MD_HANDLE md;
+       md = v3_elg_fingerprint_md(pkc);
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
+       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( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
        lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
@@ -155,7 +240,7 @@ datestr_from_pkc( PKT_public_cert *pkc )
     time_t atime = pkc->timestamp;
 
     tp = gmtime( &atime );
-    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     return buffer;
 }
 
@@ -167,7 +252,7 @@ datestr_from_skc( PKT_secret_cert *skc )
     time_t atime = skc->timestamp;
 
     tp = gmtime( &atime );
-    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     return buffer;
 }
 
@@ -179,7 +264,7 @@ datestr_from_sig( PKT_signature *sig )
     time_t atime = sig->timestamp;
 
     tp = gmtime( &atime );
-    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
+    sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     return buffer;
 }
 
@@ -213,71 +298,45 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
     return p;
 }
 
+
+
+
 byte *
 fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
 {
     byte *p, *buf, *array;
+    const char *dp;
     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);
+       MD_HANDLE md;
+       md = v3_elg_fingerprint_md(pkc);
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
        array = m_alloc( 20 );
        len = 20;
        memcpy(array, dp, 20 );
-       rmd160_close(md);
+       md_close(md);
     }
     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       MD5HANDLE md;
+       MD_HANDLE md;
 
-       md = md5_open(0);
+       md = md_open( DIGEST_ALGO_MD5, 0);
        p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
        for( ; !*p && n; p++, n-- )
            ;
-       md5_write( md, p, n );
+       md_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 );
+       md_write( md, p, n );
        m_free(buf);
-       md5_final(md);
+       md_final(md);
        array = m_alloc( 16 );
        len = 16;
-       memcpy(array, md5_read(md), 16 );
-       md5_close(md);
+       memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
+       md_close(md);
     }
     else {
        array = m_alloc(1);