2002-03-25 23:16:26 +03:00
/** \ingroup rpmio signature
* \ file rpmio / rpmpgp . c
* Routines to handle RFC - 2440 detached signatures .
*/
# include "system.h"
# include "rpmio_internal.h"
# include "debug.h"
/*@unchecked@*/
static int _debug = 0 ;
/*@unchecked@*/
static int _print = 0 ;
/*@unchecked@*/
/*@null@*/ static struct pgpDig_s * _dig = NULL ;
/*@unchecked@*/
/*@null@*/ static struct pgpDigParams_s * _digp = NULL ;
# ifdef DYING
/* This is the unarmored RPM-GPG-KEY public key. */
const char * redhatPubKeyDSA = " \
mQGiBDfqVDgRBADBKr3Bl6PO8BQ0H8sJoD6p9U7Yyl7pjtZqioviPwXP + DCWd4u8 \ n \
HQzcxAZ57m8ssA1LK1Fx93coJhDzM130 + p5BG9mYSWShLabR3N1KXdXQYYcowTOM \ n \
GxdwYRGr1Spw8QydLhjVfU1VSl4xt6bupPbWJbyjkg5Z3P7BlUOUJmrx3wCgobNV \ n \
EDGaWYJcch5z5B1of / 41 G8kEAKii6q7Gu / vhXXnLS6m15oNnPVybyngiw / 23 dKjS \ n \
ZVG7rKANEK2mxg1VB + vc / uUc4k49UxJJfCZg1gu1sPFV3GSa + Y / 7 jsiLktQvCiLP \ n \
lncQt1dV + ENmHR5BdIDPWDzKBVbgWnSDnqQ6KrZ7T6AlZ74VMpjGxxkWU6vV2xsW \ n \
XCLPA / 9 P / vtImA8CZN3jxGgtK5GGtDNJ / cMhhuv5tnfwFg4b / VGo2Jr8mhLUqoIb \ n \
E6zeGAmZbUpdckDco8D5fiFmqTf5 + + + pCEpJLJkkzel / 32 N2w4qzPrcRMCiBURES \ n \
PjCLd4Y5rPoU8E4kOHc / 4 BuHN903tiCsCPloCrWsQZ7UdxfQ5LQiUmVkIEhhdCwg \ n \
SW5jIDxzZWN1cml0eUByZWRoYXQuY29tPohVBBMRAgAVBQI36lQ4AwsKAwMVAwID \ n \
FgIBAheAAAoJECGRgM3bQqYOsBQAnRVtg7B25Hm11PHcpa8FpeddKiq2AJ9aO8sB \ n \
XmLDmPOEFI75mpTrKYHF6rkCDQQ36lRyEAgAokgI2xJ + 3 bZsk8jRA8ORIX8DH05U \ n \
lMH27qFYzLbT6npXwXYIOtVn0K2 / iMDj + oEB1Aa2au4OnddYaLWp06v3d + XyS0t + \ n \
5 ab2ZfIQzdh7wCwxqRkzR + / H5TLYbMG + hvtTdylfqIX0WEfoOXMtWEGSVwyUsnM3 \ n \
Jy3LOi48rQQSCKtCAUdV20FoIGWhwnb / gHU1BnmES6UdQujFBE6EANqPhp0coYoI \ n \
hHJ2oIO8ujQItvvNaU88j / s / izQv5e7MXOgVSjKe / WX3s2JtB / tW7utpy12wh1J + \ n \
JsFdbLV / t8CozUTpJgx5mVA3RKlxjTA + On + 1 IEUWioB + iVfT7Ov / 0 kcAzwADBQf9 \ n \
E4SKCWRand8K0XloMYgmipxMhJNnWDMLkokvbMNTUoNpSfRoQJ9EheXDxwMpTPwK \ n \
ti / PYrrL2J11P2ed0x7zm8v3gLrY0cue1iSba + 8 glY + p31ZPOr5ogaJw7ZARgoS8 \ n \
BwjyRymXQp + 8 Dete0TELKOL2 / itDOPGHW07SsVWOR6cmX4VlRRcWB5KejaNvdrE5 \ n \
4 XFtOd04NMgWI63uqZc4zkRa + kwEZtmbz3tHSdRCCE + Y7YVP6IUf / w6YPQFQriWY \ n \
FiA6fD10eB + BlIUqIw80VgjsBKmCwvKkn4jg8kibXgj4 / TzQSx77uYokw1EqQ2wk \ n \
OZoaEtcubsNMquuLCMWijYhGBBgRAgAGBQI36lRyAAoJECGRgM3bQqYOhyYAnj7h \ n \
VDY / FJAGqmtZpwVp9IlitW5tAJ4xQApr / jNFZCTksnI + 4 O1765F7tA = = \ n \
" ;
/* This is the unarmored RPM-PGP-KEY public key. */
const char * redhatPubKeyRSA = " \
mQCNAzEpXjUAAAEEAKG4 / V9oUSiDc9wIge6Bmg6erDGCLzmFyioAho8kDIJSrcmi \ n \
F9qTdPq + fj726pgW1iSb0Y7syZn9Y2lgQm5HkPODfNi8eWyTFSxbr8ygosLRClTP \ n \
xqHVhtInGrfZNLoSpv1LdWOme0yOpOQJnghdOMzKXpgf5g84vaUg6PHLopv5AAUR \ n \
tCpSZWQgSGF0IFNvZnR3YXJlLCBJbmMuIDxyZWRoYXRAcmVkaGF0LmNvbT6JAJUD \ n \
BRAyA5tUoyDApfg4JKEBAUzSA / 9 QdcVsu955vVyZDk8uvOXWV0X3voT9B3aYMFvj \ n \
UNHUD6F1VFruwQHVKbGJEq1o5MOA6OXKR3vJZStXEMF47TWXJfQaflgl8ywZTH5W \ n \
+ eMlKau6Nr0labUV3lmsAE4Vsgu8NCkzIrp2wNVbeW2ZAXtrKswV + refLquUhp7l \ n \
wMpH9IkAdQMFEDGttkRNdXhbO1TgGQEBAGoC / j6C22PqXIyqZc6fG6J6Jl / T5kFG \ n \
xH1pKIzua5WCDDugAgnuOJgywa4pegT4UqwEZiMTAlwT6dmG1CXgKB + 5 V7lnCjDc \ n \
JZLni0iztoe08ig6fJrjNGXljf7KYXzgwBftQokAlQMFEDMQzo2MRVM9rfPulQEB \ n \
pLoD / 1 / MWv3u0Paiu14XRvDrBaJ7BmG2 / 48 bA5vKOzpvvoNRO95YS7ZEtqErXA7Y \ n \
DRO8 + C8f6PAILMk7kCk4lNMscS / ZRzu5 + J8cv4ejsFvxgJBBU3Zgp8AWdWOpvZ0I \ n \
wW / / HoDUGhOxlEtymljIMFBkj4SysHWhCBUfA9Xy86kouTJQiQCVAwUQMxDOQ50a \ n \
feTWLUSJAQFnYQQAkt9nhMTeioREB1DvJt + vsFyOj / / o3ThqK5ySEP3dgj62iaQp \ n \
JrBmAe5XZPw25C / TXAf + x27H8h2QbKgq49VtsElFexc6wO + uq85fAPDdyE + 2 XyNE \ n \
njGZkY / TP2F / jTB0sAwJO + xFCHmSYkcBjzxK / 2L MD + O7rwp2UCUhhl9QhhqJAJUD \ n \
BRAx5na6pSDo8cuim / kBARmjA / 4l DVnV2h9KiNabp9oE38wmGgu5m5XgUHW8L6du \ n \
iQDnwO5IgXN2vDpKGxbgtwv6iYYmGd8IRQ66uJvOsxSv3OR7J7LkCHuI2b / s0AZn \ n \
c79DZaJ2ChUCZlbNQBMeEdrFWif9NopY + d5 + 2 tby1onu9XOFMMvomxL3NhctElYR \ n \
HC8Xw4kAlQMFEDHmdTtURTdEKY1MpQEBEtEEAMZbp1ZFrjiHkj2aLFC1S8dGRbSH \ n \
GUdnLP9qLPFgmWekp9E0o8ZztALGVdqPfPF3N / JJ + AL4IMrfojd7 + eZKw36Mdvtg \ n \
dPI + Oz4sxHDbDynZ2qspD9Om5yYuxuz / Xq + 9 nO2IlsAnEYw3ag3cxat0kvxpOPRe \ n \
Yy + vFpgfDNizr3MgiQBVAwUQMXNMXCjtrosVMemRAQEDnwH7BsJrnnh91nI54LAK \ n \
Gcq3pr8ld0PAtWJmNRGQvUlpEMXUSnu59j2P1ogPNjL3PqKdVxk5Jqgcr8TPQMf3 \ n \
V4fqXokAlQMFEDFy + 8 YiEmsRQ3LyzQEB + TwD / 03 QDslXLg5F3zj4zf0yI6ikT0be \ n \
5 OhZv2pnkb80qgdHzFRxBOYmSoueRKdQJASd8F9ue4b3bmf / Y7ikiY0DblvxcXB2 \ n \
sz1Pu8i2Zn9u8SKuxNIoVvM8 / STRVkgPfvL5QjAWMHT9Wvg81XcI2yXJzrt / 2f 2 g \ n \
mNpWIvVOOT85rVPIiQCVAwUQMVPRlBlzviMjNHElAQG1nwP / fpVX6nKRWJCSFeB7 \ n \
leZ4lb + y1uMsMVv0n7agjJVw13SXaA267y7VWCBlnhsCemxEugqEIkI4lu / 1 mgtw \ n \
WPWSE0BOIVjj0AA8zp2T0H3ZCCMbiFAFJ1P2Gq2rKr8QrOb / 08 oH1lEzyz0j / jKh \ n \
qiXAxdlB1wojQB6yLbHvTIe3rZGJAHUDBRAxKetfzauiKSJ6LJEBAed / AvsEiGgj \ n \
TQzhsZcUuRNrQpV0cDGH9Mpril7P7K7yFIzju8biB + Cu6nEknSOHlMLl8usObVlk \ n \
d8Wf14soHC7SjItiGSKtI8JhauzBJPl6fDDeyHGsJKo9f9adKeBMCipCFOuJAJUD \ n \
BRAxKeqWRHFTaIK / x + 0 BAY6eA / 4 m5X4gs1UwOUIRnljo9a0cVs6ITL554J9vSCYH \ n \
Zzd87kFwdf5W1Vd82HIkRzcr6cp33E3IDkRzaQCMVw2me7HePP7 + 4 Ry2q3EeZMbm \ n \
NE + + VzkxjikzpRb2 + F5nGB2UdsElkgbXinswebiuOwOrocLbz6JFdDsJPcT5gVfi \ n \
z15FuA = = \ n \
" ;
# endif /* DYING */
struct pgpValTbl_s pgpSigTypeTbl [ ] = {
{ PGPSIGTYPE_BINARY , " Binary document signature " } ,
{ PGPSIGTYPE_TEXT , " Text document signature " } ,
{ PGPSIGTYPE_STANDALONE , " Standalone signature " } ,
{ PGPSIGTYPE_GENERIC_CERT , " Generic certification of a User ID and Public Key " } ,
{ PGPSIGTYPE_PERSONA_CERT , " Persona certification of a User ID and Public Key " } ,
{ PGPSIGTYPE_CASUAL_CERT , " Casual certification of a User ID and Public Key " } ,
{ PGPSIGTYPE_POSITIVE_CERT , " Positive certification of a User ID and Public Key " } ,
{ PGPSIGTYPE_SUBKEY_BINDING , " Subkey Binding Signature " } ,
{ PGPSIGTYPE_SIGNED_KEY , " Signature directly on a key " } ,
{ PGPSIGTYPE_KEY_REVOKE , " Key revocation signature " } ,
{ PGPSIGTYPE_SUBKEY_REVOKE , " Subkey revocation signature " } ,
{ PGPSIGTYPE_CERT_REVOKE , " Certification revocation signature " } ,
{ PGPSIGTYPE_TIMESTAMP , " Timestamp signature " } ,
{ - 1 , " Unknown signature type " } ,
} ;
struct pgpValTbl_s pgpPubkeyTbl [ ] = {
{ PGPPUBKEYALGO_RSA , " RSA " } ,
{ PGPPUBKEYALGO_RSA_ENCRYPT , " RSA(Encrypt-Only) " } ,
{ PGPPUBKEYALGO_RSA_SIGN , " RSA(Sign-Only) " } ,
{ PGPPUBKEYALGO_ELGAMAL_ENCRYPT , " Elgamal(Encrypt-Only) " } ,
{ PGPPUBKEYALGO_DSA , " DSA " } ,
{ PGPPUBKEYALGO_EC , " Elliptic Curve " } ,
{ PGPPUBKEYALGO_ECDSA , " ECDSA " } ,
{ PGPPUBKEYALGO_ELGAMAL , " Elgamal " } ,
{ PGPPUBKEYALGO_DH , " Diffie-Hellman (X9.42) " } ,
{ - 1 , " Unknown public key algorithm " } ,
} ;
struct pgpValTbl_s pgpSymkeyTbl [ ] = {
{ PGPSYMKEYALGO_PLAINTEXT , " Plaintext " } ,
{ PGPSYMKEYALGO_IDEA , " IDEA " } ,
{ PGPSYMKEYALGO_TRIPLE_DES , " 3DES " } ,
{ PGPSYMKEYALGO_CAST5 , " CAST5 " } ,
{ PGPSYMKEYALGO_BLOWFISH , " BLOWFISH " } ,
{ PGPSYMKEYALGO_SAFER , " SAFER " } ,
{ PGPSYMKEYALGO_DES_SK , " DES/SK " } ,
{ PGPSYMKEYALGO_AES_128 , " AES(128-bit key) " } ,
{ PGPSYMKEYALGO_AES_192 , " AES(192-bit key) " } ,
{ PGPSYMKEYALGO_AES_256 , " AES(256-bit key) " } ,
{ PGPSYMKEYALGO_TWOFISH , " TWOFISH " } ,
{ - 1 , " Unknown symmetric key algorithm " } ,
} ;
struct pgpValTbl_s pgpCompressionTbl [ ] = {
{ PGPCOMPRESSALGO_NONE , " Uncompressed " } ,
{ PGPCOMPRESSALGO_ZIP , " ZIP " } ,
{ PGPCOMPRESSALGO_ZLIB , " ZLIB " } ,
{ - 1 , " Unknown compression algorithm " } ,
} ;
struct pgpValTbl_s pgpHashTbl [ ] = {
{ PGPHASHALGO_MD5 , " MD5 " } ,
{ PGPHASHALGO_SHA1 , " SHA1 " } ,
{ PGPHASHALGO_RIPEMD160 , " RIPEMD160 " } ,
{ PGPHASHALGO_MD2 , " MD2 " } ,
{ PGPHASHALGO_TIGER192 , " TIGER192 " } ,
{ PGPHASHALGO_HAVAL_5_160 , " HAVAL-5-160 " } ,
{ - 1 , " Unknown hash algorithm " } ,
} ;
/*@-exportlocal -exportheadervar@*/
/*@observer@*/ /*@unchecked@*/
struct pgpValTbl_s pgpKeyServerPrefsTbl [ ] = {
{ 0x80 , " No-modify " } ,
{ - 1 , " Unknown key server preference " } ,
} ;
/*@=exportlocal =exportheadervar@*/
struct pgpValTbl_s pgpSubTypeTbl [ ] = {
{ PGPSUBTYPE_SIG_CREATE_TIME , " signature creation time " } ,
{ PGPSUBTYPE_SIG_EXPIRE_TIME , " signature expiration time " } ,
{ PGPSUBTYPE_EXPORTABLE_CERT , " exportable certification " } ,
{ PGPSUBTYPE_TRUST_SIG , " trust signature " } ,
{ PGPSUBTYPE_REGEX , " regular expression " } ,
{ PGPSUBTYPE_REVOCABLE , " revocable " } ,
{ PGPSUBTYPE_KEY_EXPIRE_TIME , " key expiration time " } ,
{ PGPSUBTYPE_BACKWARD_COMPAT , " placeholder for backward compatibility " } ,
{ PGPSUBTYPE_PREFER_SYMKEY , " preferred symmetric algorithms " } ,
{ PGPSUBTYPE_REVOKE_KEY , " revocation key " } ,
{ PGPSUBTYPE_ISSUER_KEYID , " issuer key ID " } ,
{ PGPSUBTYPE_NOTATION , " notation data " } ,
{ PGPSUBTYPE_PREFER_HASH , " preferred hash algorithms " } ,
{ PGPSUBTYPE_PREFER_COMPRESS , " preferred compression algorithms " } ,
{ PGPSUBTYPE_KEYSERVER_PREFERS , " key server preferences " } ,
{ PGPSUBTYPE_PREFER_KEYSERVER , " preferred key server " } ,
{ PGPSUBTYPE_PRIMARY_USERID , " primary user id " } ,
{ PGPSUBTYPE_POLICY_URL , " policy URL " } ,
{ PGPSUBTYPE_KEY_FLAGS , " key flags " } ,
{ PGPSUBTYPE_SIGNER_USERID , " signer's user id " } ,
{ PGPSUBTYPE_REVOKE_REASON , " reason for revocation " } ,
{ PGPSUBTYPE_INTERNAL_100 , " internal subpkt type 100 " } ,
{ PGPSUBTYPE_INTERNAL_101 , " internal subpkt type 101 " } ,
{ PGPSUBTYPE_INTERNAL_102 , " internal subpkt type 102 " } ,
{ PGPSUBTYPE_INTERNAL_103 , " internal subpkt type 103 " } ,
{ PGPSUBTYPE_INTERNAL_104 , " internal subpkt type 104 " } ,
{ PGPSUBTYPE_INTERNAL_105 , " internal subpkt type 105 " } ,
{ PGPSUBTYPE_INTERNAL_106 , " internal subpkt type 106 " } ,
{ PGPSUBTYPE_INTERNAL_107 , " internal subpkt type 107 " } ,
{ PGPSUBTYPE_INTERNAL_108 , " internal subpkt type 108 " } ,
{ PGPSUBTYPE_INTERNAL_109 , " internal subpkt type 109 " } ,
{ PGPSUBTYPE_INTERNAL_110 , " internal subpkt type 110 " } ,
{ - 1 , " Unknown signature subkey type " } ,
} ;
struct pgpValTbl_s pgpTagTbl [ ] = {
{ PGPTAG_PUBLIC_SESSION_KEY , " Public-Key Encrypted Session Key " } ,
{ PGPTAG_SIGNATURE , " Signature " } ,
{ PGPTAG_SYMMETRIC_SESSION_KEY , " Symmetric-Key Encrypted Session Key " } ,
{ PGPTAG_ONEPASS_SIGNATURE , " One-Pass Signature " } ,
{ PGPTAG_SECRET_KEY , " Secret Key " } ,
{ PGPTAG_PUBLIC_KEY , " Public Key " } ,
{ PGPTAG_SECRET_SUBKEY , " Secret Subkey " } ,
{ PGPTAG_COMPRESSED_DATA , " Compressed Data " } ,
{ PGPTAG_SYMMETRIC_DATA , " Symmetrically Encrypted Data " } ,
{ PGPTAG_MARKER , " Marker " } ,
{ PGPTAG_LITERAL_DATA , " Literal Data " } ,
{ PGPTAG_TRUST , " Trust " } ,
{ PGPTAG_USER_ID , " User ID " } ,
{ PGPTAG_PUBLIC_SUBKEY , " Public Subkey " } ,
{ PGPTAG_COMMENT_OLD , " Comment (from OpenPGP draft) " } ,
{ PGPTAG_PHOTOID , " PGP's photo ID " } ,
{ PGPTAG_ENCRYPTED_MDC , " Integrity protected encrypted data " } ,
{ PGPTAG_MDC , " Manipulaion detection code packet " } ,
{ PGPTAG_PRIVATE_60 , " Private #60 " } ,
{ PGPTAG_COMMENT , " Comment " } ,
{ PGPTAG_PRIVATE_62 , " Private #62 " } ,
{ PGPTAG_CONTROL , " Control (GPG) " } ,
{ - 1 , " Unknown packet tag " } ,
} ;
struct pgpValTbl_s pgpArmorTbl [ ] = {
{ PGPARMOR_MESSAGE , " MESSAGE " } ,
{ PGPARMOR_PUBKEY , " PUBLIC KEY BLOCK " } ,
{ PGPARMOR_SIGNATURE , " SIGNATURE " } ,
{ PGPARMOR_SIGNED_MESSAGE , " SIGNED MESSAGE " } ,
{ PGPARMOR_FILE , " ARMORED FILE " } ,
{ PGPARMOR_PRIVKEY , " PRIVATE KEY BLOCK " } ,
{ PGPARMOR_SECKEY , " SECRET KEY BLOCK " } ,
{ - 1 , " Unknown armor block " }
} ;
struct pgpValTbl_s pgpArmorKeyTbl [ ] = {
{ PGPARMORKEY_VERSION , " Version: " } ,
{ PGPARMORKEY_COMMENT , " Comment: " } ,
{ PGPARMORKEY_MESSAGEID , " MessageID: " } ,
{ PGPARMORKEY_HASH , " Hash: " } ,
{ PGPARMORKEY_CHARSET , " Charset: " } ,
{ - 1 , " Unknown armor key " }
} ;
/**
* Wrapper to free ( 3 ) , hides const compilation noise , permit NULL , return NULL .
* @ param p memory to free
* @ return NULL always
*/
/*@unused@*/ static inline /*@null@*/ void *
_free ( /*@only@*/ /*@null@*/ /*@out@*/ const void * p )
/*@modifies p @*/
{
if ( p ! = NULL ) free ( ( void * ) p ) ;
return NULL ;
}
static void pgpPrtNL ( void )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
if ( ! _print ) return ;
fprintf ( stderr , " \n " ) ;
}
static void pgpPrtInt ( const char * pre , int i )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
if ( ! _print ) return ;
if ( pre & & * pre )
fprintf ( stderr , " %s " , pre ) ;
fprintf ( stderr , " %d " , i ) ;
}
static void pgpPrtStr ( const char * pre , const char * s )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
if ( ! _print ) return ;
if ( pre & & * pre )
fprintf ( stderr , " %s " , pre ) ;
fprintf ( stderr , " %s " , s ) ;
}
static void pgpPrtHex ( const char * pre , const byte * p , unsigned int plen )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
if ( ! _print ) return ;
if ( pre & & * pre )
fprintf ( stderr , " %s " , pre ) ;
fprintf ( stderr , " %s " , pgpHexStr ( p , plen ) ) ;
}
void pgpPrtVal ( const char * pre , pgpValTbl vs , byte val )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
if ( ! _print ) return ;
if ( pre & & * pre )
fprintf ( stderr , " %s " , pre ) ;
fprintf ( stderr , " %s(%u) " , pgpValStr ( vs , val ) , ( unsigned ) val ) ;
}
/**
*/
/*@unused@*/ static /*@observer@*/
const char * pgpMpiHex ( const byte * p )
/*@*/
{
static char prbuf [ 2048 ] ;
char * t = prbuf ;
t = pgpHexCvt ( t , p + 2 , pgpMpiLen ( p ) - 2 ) ;
return prbuf ;
}
static void pgpHexSet ( const char * pre , int lbits ,
/*@out@*/ mp32number * mpn , const byte * p )
/*@globals fileSystem @*/
/*@modifies *mpn, fileSystem @*/
{
unsigned int mbits = pgpMpiBits ( p ) ;
unsigned int nbits = ( lbits > mbits ? lbits : mbits ) ;
unsigned int nbytes = ( ( nbits + 7 ) > > 3 ) ;
char * t = xmalloc ( 2 * nbytes + 1 ) ;
unsigned int ix = 2 * ( ( nbits - mbits ) > > 3 ) ;
if ( _debug )
fprintf ( stderr , " *** mbits %u nbits %u nbytes %u t %p[%d] ix %u \n " , mbits , nbits , nbytes , t , ( 2 * nbytes + 1 ) , ix ) ;
if ( ix > 0 ) memset ( t , ( int ) ' 0 ' , ix ) ;
strcpy ( t + ix , pgpMpiHex ( p ) ) ;
if ( _debug )
fprintf ( stderr , " *** %s %s \n " , pre , t ) ;
mp32nsethex ( mpn , t ) ;
t = _free ( t ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t %s " , pre ) , mp32println ( mpn - > size , mpn - > data ) ;
2002-03-25 23:16:26 +03:00
}
int pgpPrtSubType ( const byte * h , unsigned int hlen )
{
const byte * p = h ;
unsigned plen ;
int i ;
while ( hlen > 0 ) {
i = pgpLen ( p , & plen ) ;
p + = i ;
hlen - = i ;
pgpPrtVal ( " " , pgpSubTypeTbl , p [ 0 ] ) ;
switch ( * p ) {
case PGPSUBTYPE_PREFER_SYMKEY : /* preferred symmetric algorithms */
for ( i = 1 ; i < plen ; i + + )
pgpPrtVal ( " " , pgpSymkeyTbl , p [ i ] ) ;
/*@switchbreak@*/ break ;
case PGPSUBTYPE_PREFER_HASH : /* preferred hash algorithms */
for ( i = 1 ; i < plen ; i + + )
pgpPrtVal ( " " , pgpHashTbl , p [ i ] ) ;
/*@switchbreak@*/ break ;
case PGPSUBTYPE_PREFER_COMPRESS : /* preferred compression algorithms */
for ( i = 1 ; i < plen ; i + + )
pgpPrtVal ( " " , pgpCompressionTbl , p [ i ] ) ;
/*@switchbreak@*/ break ;
case PGPSUBTYPE_KEYSERVER_PREFERS : /* key server preferences */
for ( i = 1 ; i < plen ; i + + )
pgpPrtVal ( " " , pgpKeyServerPrefsTbl , p [ i ] ) ;
/*@switchbreak@*/ break ;
case PGPSUBTYPE_SIG_CREATE_TIME :
/*@-mods -mayaliasunique @*/
2002-08-03 20:35:14 +04:00
# ifdef DYING
if ( _digp & & _digp - > tag = = PGPTAG_PUBLIC_KEY )
# else
if ( _digp & & ! ( _digp - > saved & PGPDIG_SAVED_TIME ) )
# endif
{
_digp - > saved | = PGPDIG_SAVED_TIME ;
2002-03-25 23:16:26 +03:00
memcpy ( _digp - > time , p + 1 , sizeof ( _digp - > time ) ) ;
}
/*@=mods =mayaliasunique @*/
/*@fallthrough@*/
case PGPSUBTYPE_SIG_EXPIRE_TIME :
case PGPSUBTYPE_KEY_EXPIRE_TIME :
if ( ( plen - 1 ) = = 4 ) {
time_t t = pgpGrab ( p + 1 , plen - 1 ) ;
if ( _print )
fprintf ( stderr , " %-24.24s(0x%08x) " , ctime ( & t ) , ( unsigned ) t ) ;
} else
pgpPrtHex ( " " , p + 1 , plen - 1 ) ;
/*@switchbreak@*/ break ;
case PGPSUBTYPE_ISSUER_KEYID : /* issuer key ID */
/*@-mods -mayaliasunique @*/
2002-08-03 20:35:14 +04:00
# ifdef DYING
if ( _digp & & _digp - > tag = = PGPTAG_PUBLIC_KEY )
# else
if ( _digp & & ! ( _digp - > saved & PGPDIG_SAVED_ID ) )
# endif
{
_digp - > saved | = PGPDIG_SAVED_ID ;
2002-03-25 23:16:26 +03:00
memcpy ( _digp - > signid , p + 1 , sizeof ( _digp - > signid ) ) ;
}
/*@=mods =mayaliasunique @*/
/*@fallthrough@*/
case PGPSUBTYPE_EXPORTABLE_CERT :
case PGPSUBTYPE_TRUST_SIG :
case PGPSUBTYPE_REGEX :
case PGPSUBTYPE_REVOCABLE :
case PGPSUBTYPE_BACKWARD_COMPAT :
case PGPSUBTYPE_REVOKE_KEY :
case PGPSUBTYPE_NOTATION :
case PGPSUBTYPE_PREFER_KEYSERVER :
case PGPSUBTYPE_PRIMARY_USERID :
case PGPSUBTYPE_POLICY_URL :
case PGPSUBTYPE_KEY_FLAGS :
case PGPSUBTYPE_SIGNER_USERID :
case PGPSUBTYPE_REVOKE_REASON :
case PGPSUBTYPE_INTERNAL_100 :
case PGPSUBTYPE_INTERNAL_101 :
case PGPSUBTYPE_INTERNAL_102 :
case PGPSUBTYPE_INTERNAL_103 :
case PGPSUBTYPE_INTERNAL_104 :
case PGPSUBTYPE_INTERNAL_105 :
case PGPSUBTYPE_INTERNAL_106 :
case PGPSUBTYPE_INTERNAL_107 :
case PGPSUBTYPE_INTERNAL_108 :
case PGPSUBTYPE_INTERNAL_109 :
case PGPSUBTYPE_INTERNAL_110 :
default :
pgpPrtHex ( " " , p + 1 , plen - 1 ) ;
/*@switchbreak@*/ break ;
}
pgpPrtNL ( ) ;
p + = plen ;
hlen - = plen ;
}
return 0 ;
}
/*@-varuse =readonlytrans @*/
/*@observer@*/ /*@unchecked@*/
static const char * pgpSigRSA [ ] = {
" m**d = " ,
NULL ,
} ;
/*@observer@*/ /*@unchecked@*/
static const char * pgpSigDSA [ ] = {
" r = " ,
" s = " ,
NULL ,
} ;
/*@=varuse =readonlytrans @*/
static int pgpPrtSigParams ( /*@unused@*/ pgpTag tag , byte pubkey_algo , byte sigtype ,
const byte * p , const byte * h , unsigned int hlen )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
int i ;
for ( i = 0 ; p < & h [ hlen ] ; i + + , p + = pgpMpiLen ( p ) ) {
if ( pubkey_algo = = PGPPUBKEYALGO_RSA ) {
if ( i > = 1 ) break ;
/*@-mods@*/
if ( _dig & &
( sigtype = = PGPSIGTYPE_BINARY | | sigtype = = PGPSIGTYPE_TEXT ) )
{
switch ( i ) {
case 0 : /* m**d */
mp32nsethex ( & _dig - > c , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t m**d = " ) , mp32println ( _dig - > c . size , _dig - > c . data ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
default :
/*@switchbreak@*/ break ;
}
}
/*@=mods@*/
pgpPrtStr ( " " , pgpSigRSA [ i ] ) ;
} else if ( pubkey_algo = = PGPPUBKEYALGO_DSA ) {
if ( i > = 2 ) break ;
/*@-mods@*/
if ( _dig & &
( sigtype = = PGPSIGTYPE_BINARY | | sigtype = = PGPSIGTYPE_TEXT ) )
{
switch ( i ) {
case 0 : /* r */
pgpHexSet ( pgpSigDSA [ i ] , 160 , & _dig - > r , p ) ;
/*@switchbreak@*/ break ;
case 1 : /* s */
pgpHexSet ( pgpSigDSA [ i ] , 160 , & _dig - > s , p ) ;
/*@switchbreak@*/ break ;
default :
/*@switchbreak@*/ break ;
}
}
/*@=mods@*/
pgpPrtStr ( " " , pgpSigDSA [ i ] ) ;
} else {
if ( _print )
fprintf ( stderr , " %7d " , i ) ;
}
pgpPrtStr ( " " , pgpMpiStr ( p ) ) ;
pgpPrtNL ( ) ;
}
return 0 ;
}
int pgpPrtSig ( pgpTag tag , const byte * h , unsigned int hlen )
{
byte version = h [ 0 ] ;
byte * p ;
unsigned plen ;
int rc ;
switch ( version ) {
case 3 :
{ pgpPktSigV3 v = ( pgpPktSigV3 ) h ;
time_t t ;
if ( v - > hashlen ! = 5 ) {
fprintf ( stderr , " hashlen(%u) != 5 \n " , ( unsigned ) v - > hashlen ) ;
return 1 ;
}
pgpPrtVal ( " V3 " , pgpTagTbl , tag ) ;
pgpPrtVal ( " " , pgpPubkeyTbl , v - > pubkey_algo ) ;
pgpPrtVal ( " " , pgpHashTbl , v - > hash_algo ) ;
pgpPrtVal ( " " , pgpSigTypeTbl , v - > sigtype ) ;
pgpPrtNL ( ) ;
t = pgpGrab ( v - > time , sizeof ( v - > time ) ) ;
if ( _print )
fprintf ( stderr , " %-24.24s(0x%08x) " , ctime ( & t ) , ( unsigned ) t ) ;
pgpPrtNL ( ) ;
pgpPrtHex ( " signer keyid " , v - > signid , sizeof ( v - > signid ) ) ;
plen = pgpGrab ( v - > signhash16 , sizeof ( v - > signhash16 ) ) ;
pgpPrtHex ( " signhash16 " , v - > signhash16 , sizeof ( v - > signhash16 ) ) ;
pgpPrtNL ( ) ;
/*@-mods@*/
if ( _digp & & _digp - > pubkey_algo = = 0 ) {
_digp - > version = v - > version ;
_digp - > hashlen = v - > hashlen ;
_digp - > sigtype = v - > sigtype ;
_digp - > hash = memcpy ( xmalloc ( v - > hashlen ) , & v - > sigtype , v - > hashlen ) ;
memcpy ( _digp - > time , v - > time , sizeof ( _digp - > time ) ) ;
memcpy ( _digp - > signid , v - > signid , sizeof ( _digp - > signid ) ) ;
_digp - > pubkey_algo = v - > pubkey_algo ;
_digp - > hash_algo = v - > hash_algo ;
memcpy ( _digp - > signhash16 , v - > signhash16 , sizeof ( _digp - > signhash16 ) ) ;
}
/*@=mods@*/
p = ( ( byte * ) v ) + sizeof ( * v ) ;
rc = pgpPrtSigParams ( tag , v - > pubkey_algo , v - > sigtype , p , h , hlen ) ;
} break ;
case 4 :
{ pgpPktSigV4 v = ( pgpPktSigV4 ) h ;
pgpPrtVal ( " V4 " , pgpTagTbl , tag ) ;
pgpPrtVal ( " " , pgpPubkeyTbl , v - > pubkey_algo ) ;
pgpPrtVal ( " " , pgpHashTbl , v - > hash_algo ) ;
pgpPrtVal ( " " , pgpSigTypeTbl , v - > sigtype ) ;
pgpPrtNL ( ) ;
p = & v - > hashlen [ 0 ] ;
plen = pgpGrab ( v - > hashlen , sizeof ( v - > hashlen ) ) ;
p + = sizeof ( v - > hashlen ) ;
if ( _debug & & _print )
fprintf ( stderr , " hash[%u] -- %s \n " , plen , pgpHexStr ( p , plen ) ) ;
2002-08-03 20:35:14 +04:00
/*@-mods@*/
2002-03-25 23:16:26 +03:00
if ( _digp & & _digp - > pubkey_algo = = 0 ) {
2002-08-03 20:35:14 +04:00
_digp - > hashlen = sizeof ( * v ) + plen ;
_digp - > hash = memcpy ( xmalloc ( _digp - > hashlen ) , v , _digp - > hashlen ) ;
2002-03-25 23:16:26 +03:00
}
2002-08-03 20:35:14 +04:00
/*@=mods@*/
2002-03-25 23:16:26 +03:00
( void ) pgpPrtSubType ( p , plen ) ;
p + = plen ;
plen = pgpGrab ( p , 2 ) ;
p + = 2 ;
if ( _debug & & _print )
fprintf ( stderr , " unhash[%u] -- %s \n " , plen , pgpHexStr ( p , plen ) ) ;
( void ) pgpPrtSubType ( p , plen ) ;
p + = plen ;
plen = pgpGrab ( p , 2 ) ;
pgpPrtHex ( " signhash16 " , p , 2 ) ;
pgpPrtNL ( ) ;
/*@-mods@*/
if ( _digp & & _digp - > pubkey_algo = = 0 ) {
_digp - > version = v - > version ;
_digp - > sigtype = v - > sigtype ;
_digp - > pubkey_algo = v - > pubkey_algo ;
_digp - > hash_algo = v - > hash_algo ;
memcpy ( _digp - > signhash16 , p , sizeof ( _digp - > signhash16 ) ) ;
}
/*@=mods@*/
p + = 2 ;
rc = pgpPrtSigParams ( tag , v - > pubkey_algo , v - > sigtype , p , h , hlen ) ;
} break ;
default :
rc = 1 ;
break ;
}
return rc ;
}
/*@-varuse =readonlytrans @*/
/*@observer@*/ /*@unchecked@*/
static const char * pgpPublicRSA [ ] = {
" n = " ,
" e = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# ifdef NOTYET
2002-03-25 23:16:26 +03:00
/*@observer@*/ /*@unchecked@*/
static const char * pgpSecretRSA [ ] = {
" d = " ,
" p = " ,
" q = " ,
" u = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# endif
2002-03-25 23:16:26 +03:00
/*@observer@*/ /*@unchecked@*/
static const char * pgpPublicDSA [ ] = {
" p = " ,
" q = " ,
" g = " ,
" y = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# ifdef NOTYET
2002-03-25 23:16:26 +03:00
/*@observer@*/ /*@unchecked@*/
static const char * pgpSecretDSA [ ] = {
" x = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# endif
2002-03-25 23:16:26 +03:00
/*@observer@*/ /*@unchecked@*/
static const char * pgpPublicELGAMAL [ ] = {
" p = " ,
" g = " ,
" y = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# ifdef NOTYET
2002-03-25 23:16:26 +03:00
/*@observer@*/ /*@unchecked@*/
static const char * pgpSecretELGAMAL [ ] = {
" x = " ,
NULL ,
} ;
2003-11-24 21:59:03 +03:00
# endif
2002-03-25 23:16:26 +03:00
/*@=varuse =readonlytrans @*/
static const byte * pgpPrtPubkeyParams ( byte pubkey_algo ,
/*@returned@*/ const byte * p , const byte * h , unsigned int hlen )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
int i ;
for ( i = 0 ; p < & h [ hlen ] ; i + + , p + = pgpMpiLen ( p ) ) {
if ( pubkey_algo = = PGPPUBKEYALGO_RSA ) {
if ( i > = 2 ) break ;
/*@-mods@*/
if ( _dig ) {
switch ( i ) {
case 0 : /* n */
mp32bsethex ( & _dig - > rsa_pk . n , pgpMpiHex ( p ) ) ;
/* Get the keyid */
if ( _digp ) {
uint32 * np = _dig - > rsa_pk . n . modl ;
uint32 nsize = _dig - > rsa_pk . n . size ;
uint32 keyid [ 2 ] ;
# if WORDS_BIGENDIAN
keyid [ 0 ] = np [ nsize - 2 ] ;
keyid [ 1 ] = np [ nsize - 1 ] ;
# else
keyid [ 0 ] = swapu32 ( np [ nsize - 2 ] ) ;
keyid [ 1 ] = swapu32 ( np [ nsize - 1 ] ) ;
# endif
memcpy ( _digp - > signid , keyid , sizeof ( _digp - > signid ) ) ;
}
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t n = " ) , mp32println ( _dig - > rsa_pk . n . size , _dig - > rsa_pk . n . modl ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
case 1 : /* e */
mp32nsethex ( & _dig - > rsa_pk . e , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t e = " ) , mp32println ( _dig - > rsa_pk . e . size , _dig - > rsa_pk . e . data ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
default :
/*@switchbreak@*/ break ;
}
}
/*@=mods@*/
pgpPrtStr ( " " , pgpPublicRSA [ i ] ) ;
} else if ( pubkey_algo = = PGPPUBKEYALGO_DSA ) {
if ( i > = 4 ) break ;
/*@-mods@*/
if ( _dig ) {
switch ( i ) {
case 0 : /* p */
mp32bsethex ( & _dig - > p , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t p = " ) , mp32println ( _dig - > p . size , _dig - > p . modl ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
case 1 : /* q */
mp32bsethex ( & _dig - > q , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t q = " ) , mp32println ( _dig - > q . size , _dig - > q . modl ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
case 2 : /* g */
mp32nsethex ( & _dig - > g , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t g = " ) , mp32println ( _dig - > g . size , _dig - > g . data ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
case 3 : /* y */
mp32nsethex ( & _dig - > y , pgpMpiHex ( p ) ) ;
if ( _debug & & _print )
2002-08-03 21:07:51 +04:00
fprintf ( stderr , " \t y = " ) , mp32println ( _dig - > y . size , _dig - > y . data ) ;
2002-03-25 23:16:26 +03:00
/*@switchbreak@*/ break ;
default :
/*@switchbreak@*/ break ;
}
}
/*@=mods@*/
pgpPrtStr ( " " , pgpPublicDSA [ i ] ) ;
} else if ( pubkey_algo = = PGPPUBKEYALGO_ELGAMAL_ENCRYPT ) {
if ( i > = 3 ) break ;
pgpPrtStr ( " " , pgpPublicELGAMAL [ i ] ) ;
} else {
if ( _print )
fprintf ( stderr , " %7d " , i ) ;
}
/*@=mods@*/
pgpPrtStr ( " " , pgpMpiStr ( p ) ) ;
pgpPrtNL ( ) ;
}
return p ;
}
static const byte * pgpPrtSeckeyParams ( /*@unused@*/ byte pubkey_algo ,
/*@returned@*/ const byte * p , const byte * h , unsigned int hlen )
/*@globals fileSystem @*/
/*@modifies fileSystem @*/
{
int i ;
switch ( * p ) {
case 0 :
pgpPrtVal ( " " , pgpSymkeyTbl , * p ) ;
break ;
case 255 :
p + + ;
pgpPrtVal ( " " , pgpSymkeyTbl , * p ) ;
switch ( p [ 1 ] ) {
case 0x00 :
pgpPrtVal ( " simple " , pgpHashTbl , p [ 2 ] ) ;
p + = 2 ;
/*@innerbreak@*/ break ;
case 0x01 :
pgpPrtVal ( " salted " , pgpHashTbl , p [ 2 ] ) ;
pgpPrtHex ( " " , p + 3 , 8 ) ;
p + = 10 ;
/*@innerbreak@*/ break ;
case 0x03 :
pgpPrtVal ( " iterated/salted " , pgpHashTbl , p [ 2 ] ) ;
/*@-shiftnegative@*/ /* FIX: unsigned cast */
i = ( 16 + ( p [ 11 ] & 0xf ) ) < < ( ( p [ 11 ] > > 4 ) + 6 ) ;
/*@=shiftnegative@*/
pgpPrtHex ( " " , p + 3 , 8 ) ;
pgpPrtInt ( " iter " , i ) ;
p + = 11 ;
/*@innerbreak@*/ break ;
}
break ;
default :
pgpPrtVal ( " " , pgpSymkeyTbl , * p ) ;
pgpPrtHex ( " IV " , p + 1 , 8 ) ;
p + = 8 ;
break ;
}
pgpPrtNL ( ) ;
p + + ;
# ifdef NOTYET /* XXX encrypted MPI's need to be handled. */
for ( i = 0 ; p < & h [ hlen ] ; i + + , p + = pgpMpiLen ( p ) ) {
if ( pubkey_algo = = PGPPUBKEYALGO_RSA ) {
if ( pgpSecretRSA [ i ] = = NULL ) break ;
pgpPrtStr ( " " , pgpSecretRSA [ i ] ) ;
} else if ( pubkey_algo = = PGPPUBKEYALGO_DSA ) {
if ( pgpSecretDSA [ i ] = = NULL ) break ;
pgpPrtStr ( " " , pgpSecretDSA [ i ] ) ;
} else if ( pubkey_algo = = PGPPUBKEYALGO_ELGAMAL_ENCRYPT ) {
if ( pgpSecretELGAMAL [ i ] = = NULL ) break ;
pgpPrtStr ( " " , pgpSecretELGAMAL [ i ] ) ;
} else {
if ( _print )
fprintf ( stderr , " %7d " , i ) ;
}
pgpPrtStr ( " " , pgpMpiStr ( p ) ) ;
pgpPrtNL ( ) ;
}
# else
pgpPrtHex ( " secret " , p , ( hlen - ( p - h ) - 2 ) ) ;
pgpPrtNL ( ) ;
p + = ( hlen - ( p - h ) - 2 ) ;
# endif
pgpPrtHex ( " checksum " , p , 2 ) ;
pgpPrtNL ( ) ;
return p ;
}
int pgpPrtKey ( pgpTag tag , const byte * h , unsigned int hlen )
{
byte version = * h ;
const byte * p ;
unsigned plen ;
time_t t ;
int rc ;
switch ( version ) {
case 3 :
{ pgpPktKeyV3 v = ( pgpPktKeyV3 ) h ;
pgpPrtVal ( " V3 " , pgpTagTbl , tag ) ;
pgpPrtVal ( " " , pgpPubkeyTbl , v - > pubkey_algo ) ;
t = pgpGrab ( v - > time , sizeof ( v - > time ) ) ;
if ( _print )
fprintf ( stderr , " %-24.24s(0x%08x) " , ctime ( & t ) , ( unsigned ) t ) ;
plen = pgpGrab ( v - > valid , sizeof ( v - > valid ) ) ;
if ( plen ! = 0 )
fprintf ( stderr , " valid %u days " , plen ) ;
pgpPrtNL ( ) ;
/*@-mods@*/
if ( _digp & & _digp - > tag = = tag ) {
_digp - > version = v - > version ;
memcpy ( _digp - > time , v - > time , sizeof ( _digp - > time ) ) ;
_digp - > pubkey_algo = v - > pubkey_algo ;
}
/*@=mods@*/
p = ( ( byte * ) v ) + sizeof ( * v ) ;
p = pgpPrtPubkeyParams ( v - > pubkey_algo , p , h , hlen ) ;
rc = 0 ;
} break ;
case 4 :
{ pgpPktKeyV4 v = ( pgpPktKeyV4 ) h ;
pgpPrtVal ( " V4 " , pgpTagTbl , tag ) ;
pgpPrtVal ( " " , pgpPubkeyTbl , v - > pubkey_algo ) ;
t = pgpGrab ( v - > time , sizeof ( v - > time ) ) ;
if ( _print )
fprintf ( stderr , " %-24.24s(0x%08x) " , ctime ( & t ) , ( unsigned ) t ) ;
pgpPrtNL ( ) ;
/*@-mods@*/
if ( _digp & & _digp - > tag = = tag ) {
_digp - > version = v - > version ;
memcpy ( _digp - > time , v - > time , sizeof ( _digp - > time ) ) ;
_digp - > pubkey_algo = v - > pubkey_algo ;
}
/*@=mods@*/
p = ( ( byte * ) v ) + sizeof ( * v ) ;
p = pgpPrtPubkeyParams ( v - > pubkey_algo , p , h , hlen ) ;
if ( ! ( tag = = PGPTAG_PUBLIC_KEY | | tag = = PGPTAG_PUBLIC_SUBKEY ) )
p = pgpPrtSeckeyParams ( v - > pubkey_algo , p , h , hlen ) ;
rc = 0 ;
} break ;
default :
rc = 1 ;
break ;
}
return rc ;
}
int pgpPrtUserID ( pgpTag tag , const byte * h , unsigned int hlen )
{
pgpPrtVal ( " " , pgpTagTbl , tag ) ;
if ( _print )
fprintf ( stderr , " \" %.*s \" " , ( int ) hlen , ( const char * ) h ) ;
pgpPrtNL ( ) ;
/*@-mods@*/
if ( _digp ) {
char * t ;
_digp - > userid = t = memcpy ( xmalloc ( hlen + 1 ) , h , hlen ) ;
t [ hlen ] = ' \0 ' ;
}
/*@=mods@*/
return 0 ;
}
int pgpPrtComment ( pgpTag tag , const byte * h , unsigned int hlen )
{
int i = hlen ;
pgpPrtVal ( " " , pgpTagTbl , tag ) ;
if ( _print )
fprintf ( stderr , " " ) ;
while ( i > 0 ) {
int j ;
if ( * h > = ' ' & & * h < = ' z ' ) {
if ( _print )
fprintf ( stderr , " %s " , ( const char * ) h ) ;
j = strlen ( h ) ;
while ( h [ j ] = = ' \0 ' )
j + + ;
} else {
pgpPrtHex ( " " , h , i ) ;
j = i ;
}
i - = j ;
h + = j ;
}
pgpPrtNL ( ) ;
return 0 ;
}
int pgpPrtPkt ( const byte * pkt )
{
unsigned int val = * pkt ;
unsigned int pktlen ;
pgpTag tag ;
unsigned int plen ;
const byte * h ;
unsigned int hlen = 0 ;
int rc = 0 ;
/* XXX can't deal with these. */
if ( ! ( val & 0x80 ) )
return - 1 ;
if ( val & 0x40 ) {
tag = ( val & 0x3f ) ;
plen = pgpLen ( pkt + 1 , & hlen ) ;
} else {
tag = ( val > > 2 ) & 0xf ;
plen = ( 1 < < ( val & 0x3 ) ) ;
hlen = pgpGrab ( pkt + 1 , plen ) ;
}
pktlen = 1 + plen + hlen ;
h = pkt + 1 + plen ;
switch ( tag ) {
case PGPTAG_SIGNATURE :
rc = pgpPrtSig ( tag , h , hlen ) ;
break ;
case PGPTAG_PUBLIC_KEY :
case PGPTAG_PUBLIC_SUBKEY :
rc = pgpPrtKey ( tag , h , hlen ) ;
break ;
case PGPTAG_SECRET_KEY :
case PGPTAG_SECRET_SUBKEY :
rc = pgpPrtKey ( tag , h , hlen ) ;
break ;
case PGPTAG_USER_ID :
rc = pgpPrtUserID ( tag , h , hlen ) ;
break ;
case PGPTAG_COMMENT :
case PGPTAG_COMMENT_OLD :
rc = pgpPrtComment ( tag , h , hlen ) ;
break ;
case PGPTAG_RESERVED :
case PGPTAG_PUBLIC_SESSION_KEY :
case PGPTAG_SYMMETRIC_SESSION_KEY :
case PGPTAG_COMPRESSED_DATA :
case PGPTAG_SYMMETRIC_DATA :
case PGPTAG_MARKER :
case PGPTAG_LITERAL_DATA :
case PGPTAG_TRUST :
case PGPTAG_PHOTOID :
case PGPTAG_ENCRYPTED_MDC :
case PGPTAG_MDC :
case PGPTAG_PRIVATE_60 :
case PGPTAG_PRIVATE_62 :
case PGPTAG_CONTROL :
default :
pgpPrtVal ( " " , pgpTagTbl , tag ) ;
pgpPrtHex ( " " , h , hlen ) ;
pgpPrtNL ( ) ;
break ;
}
return ( rc ? - 1 : pktlen ) ;
}
struct pgpDig_s * pgpNewDig ( void )
{
struct pgpDig_s * dig = xcalloc ( 1 , sizeof ( * dig ) ) ;
return dig ;
}
2002-08-03 20:35:14 +04:00
void pgpCleanDig ( struct pgpDig_s * dig )
2002-03-25 23:16:26 +03:00
/*@modifies dig @*/
{
if ( dig ! = NULL ) {
int i ;
dig - > signature . userid = _free ( dig - > signature . userid ) ;
dig - > pubkey . userid = _free ( dig - > pubkey . userid ) ;
dig - > signature . hash = _free ( dig - > signature . hash ) ;
dig - > pubkey . hash = _free ( dig - > pubkey . hash ) ;
/*@-unqualifiedtrans@*/ /* FIX: double indirection */
for ( i = 0 ; i < 4 ; i + + ) {
dig - > signature . params [ i ] = _free ( dig - > signature . params [ i ] ) ;
dig - > pubkey . params [ i ] = _free ( dig - > pubkey . params [ i ] ) ;
}
/*@=unqualifiedtrans@*/
2002-08-03 20:35:14 +04:00
memset ( & dig - > signature , 0 , sizeof ( dig - > signature ) ) ;
memset ( & dig - > pubkey , 0 , sizeof ( dig - > pubkey ) ) ;
dig - > md5 = _free ( dig - > md5 ) ;
dig - > sha1 = _free ( dig - > sha1 ) ;
mp32nfree ( & dig - > hm ) ;
mp32nfree ( & dig - > r ) ;
mp32nfree ( & dig - > s ) ;
( void ) rsapkFree ( & dig - > rsa_pk ) ;
mp32nfree ( & dig - > m ) ;
mp32nfree ( & dig - > c ) ;
mp32nfree ( & dig - > rsahm ) ;
}
/*@-nullstate@*/
return ;
/*@=nullstate@*/
}
struct pgpDig_s * pgpFreeDig ( /*@only@*/ /*@null@*/ struct pgpDig_s * dig )
/*@modifies dig @*/
{
if ( dig ! = NULL ) {
/* DUmp the signature/pubkey data. */
pgpCleanDig ( dig ) ;
2002-03-25 23:16:26 +03:00
/*@-branchstate@*/
if ( dig - > md5ctx ! = NULL )
( void ) rpmDigestFinal ( dig - > md5ctx , NULL , NULL , 0 ) ;
/*@=branchstate@*/
dig - > md5ctx = NULL ;
2002-08-03 20:35:14 +04:00
/*@-branchstate@*/
if ( dig - > hdrsha1ctx ! = NULL )
( void ) rpmDigestFinal ( dig - > hdrsha1ctx , NULL , NULL , 0 ) ;
/*@=branchstate@*/
dig - > hdrsha1ctx = NULL ;
2002-03-25 23:16:26 +03:00
/*@-branchstate@*/
if ( dig - > sha1ctx ! = NULL )
( void ) rpmDigestFinal ( dig - > sha1ctx , NULL , NULL , 0 ) ;
/*@=branchstate@*/
dig - > sha1ctx = NULL ;
2002-08-03 20:35:14 +04:00
mp32bfree ( & dig - > p ) ;
mp32bfree ( & dig - > q ) ;
mp32nfree ( & dig - > g ) ;
mp32nfree ( & dig - > y ) ;
2002-03-25 23:16:26 +03:00
mp32nfree ( & dig - > hm ) ;
mp32nfree ( & dig - > r ) ;
mp32nfree ( & dig - > s ) ;
2002-08-03 20:35:14 +04:00
mp32bfree ( & dig - > rsa_pk . n ) ;
mp32nfree ( & dig - > rsa_pk . e ) ;
2002-03-25 23:16:26 +03:00
mp32nfree ( & dig - > m ) ;
mp32nfree ( & dig - > c ) ;
2002-08-03 20:35:14 +04:00
mp32nfree ( & dig - > hm ) ;
2002-03-25 23:16:26 +03:00
dig = _free ( dig ) ;
}
return dig ;
}
int pgpPrtPkts ( const byte * pkts , unsigned int plen ,
struct pgpDig_s * dig , int printing )
{
unsigned int val = * pkts ;
const byte * p ;
int len ;
/*@-mods@*/
_print = printing ;
_dig = dig ;
if ( dig ! = NULL & & ( val & 0x80 ) ) {
pgpTag tag = ( val & 0x40 ) ? ( val & 0x3f ) : ( ( val > > 2 ) & 0xf ) ;
_digp = ( tag = = PGPTAG_SIGNATURE ) ? & _dig - > signature : & _dig - > pubkey ;
_digp - > tag = tag ;
} else
_digp = NULL ;
/*@=mods@*/
for ( p = pkts ; p < ( pkts + plen ) ; p + = len ) {
len = pgpPrtPkt ( p ) ;
if ( len < = 0 )
return len ;
}
return 0 ;
}
pgpArmor pgpReadPkts ( const char * fn , const byte * * pkt , size_t * pktlen )
{
const byte * b = NULL ;
ssize_t blen ;
const char * enc = NULL ;
const char * crcenc = NULL ;
byte * dec ;
byte * crcdec ;
size_t declen ;
size_t crclen ;
uint32 crcpkt , crc ;
const char * armortype = NULL ;
char * t , * te ;
int pstate = 0 ;
pgpArmor ec = PGPARMOR_ERROR ; /* XXX assume failure */
int rc ;
rc = rpmioSlurp ( fn , & b , & blen ) ;
if ( rc | | b = = NULL | | blen < = 0 ) {
goto exit ;
}
if ( pgpIsPkt ( b ) ) {
# ifdef NOTYET /* XXX ASCII Pubkeys only, please. */
ec = 0 ; /* XXX fish out pkt type. */
# endif
goto exit ;
}
# define TOKEQ(_s, _tok) (!strncmp((_s), (_tok), sizeof(_tok)-1))
for ( t = ( char * ) b ; t & & * t ; t = te ) {
if ( ( te = strchr ( t , ' \n ' ) ) = = NULL )
te = t + strlen ( t ) ;
else
te + + ;
switch ( pstate ) {
case 0 :
armortype = NULL ;
if ( ! TOKEQ ( t , " -----BEGIN PGP " ) )
continue ;
t + = sizeof ( " -----BEGIN PGP " ) - 1 ;
rc = pgpValTok ( pgpArmorTbl , t , te ) ;
if ( rc < 0 )
goto exit ;
if ( rc ! = PGPARMOR_PUBKEY ) /* XXX ASCII Pubkeys only, please. */
continue ;
armortype = t ;
t = te - ( sizeof ( " ----- \n " ) - 1 ) ;
if ( ! TOKEQ ( t , " ----- \n " ) )
continue ;
* t = ' \0 ' ;
pstate + + ;
/*@switchbreak@*/ break ;
case 1 :
enc = NULL ;
rc = pgpValTok ( pgpArmorKeyTbl , t , te ) ;
if ( rc > = 0 )
continue ;
if ( * t ! = ' \n ' ) {
pstate = 0 ;
continue ;
}
enc = te ; /* Start of encoded packets */
pstate + + ;
/*@switchbreak@*/ break ;
case 2 :
crcenc = NULL ;
if ( * t ! = ' = ' )
continue ;
* t + + = ' \0 ' ; /* Terminate encoded packets */
crcenc = t ; /* Start of encoded crc */
pstate + + ;
/*@switchbreak@*/ break ;
case 3 :
pstate = 0 ;
if ( ! TOKEQ ( t , " -----END PGP " ) )
goto exit ;
* t = ' \0 ' ; /* Terminate encoded crc */
t + = sizeof ( " -----END PGP " ) - 1 ;
if ( armortype = = NULL ) /* XXX can't happen */
continue ;
rc = strncmp ( t , armortype , strlen ( armortype ) ) ;
if ( rc )
continue ;
t = te - ( sizeof ( " ----- \n " ) - 1 ) ;
if ( ! TOKEQ ( t , " ----- \n " ) )
goto exit ;
if ( b64decode ( crcenc , ( void * * ) & crcdec , & crclen ) ! = 0 )
continue ;
crcpkt = pgpGrab ( crcdec , crclen ) ;
crcdec = _free ( crcdec ) ;
if ( b64decode ( enc , ( void * * ) & dec , & declen ) ! = 0 )
goto exit ;
crc = pgpCRC ( dec , declen ) ;
if ( crcpkt ! = crc )
goto exit ;
b = _free ( b ) ;
b = dec ;
blen = declen ;
ec = PGPARMOR_PUBKEY ; /* XXX ASCII Pubkeys only, please. */
goto exit ;
/*@notreached@*/ /*@switchbreak@*/ break ;
}
}
ec = PGPARMOR_NONE ;
exit :
if ( ec > PGPARMOR_NONE & & pkt )
* pkt = b ;
else if ( b ! = NULL )
b = _free ( b ) ;
if ( pktlen )
* pktlen = blen ;
return ec ;
}