- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# rpmpgp.h

Go to the documentation of this file.

    00001 #ifndef H_RPMPGP
    00002 #define H_RPMPGP
    00003
    00013 #include <string.h>
    00014 #include <stdio.h>
    00015 #include <stdlib.h>
    00016 #include <rpm/rpmtypes.h>
    00017 #include <rpm/rpmstring.h>
    00018
    00019 #ifdef __cplusplus
    00020 extern "C" {
    00021 #endif
    00022
    00025 typedef struct DIGEST_CTX_s * DIGEST_CTX;
    00026 typedef struct rpmDigestBundle_s * rpmDigestBundle;
    00027
    00030 typedef struct pgpDig_s * pgpDig;
    00031
    00034 typedef struct pgpDigParams_s * pgpDigParams;
    00035
    00036 typedef uint8_t pgpKeyID_t[8];
    00037 typedef uint8_t pgpTime_t[4];
    00038
    00041 typedef const struct pgpValTbl_s {
    00042     int val;
    00043     char const * const str;
    00044 } * pgpValTbl;
    00045
    00053 typedef enum pgpTag_e {
    00054     PGPTAG_RESERVED             =  0,
    00055     PGPTAG_PUBLIC_SESSION_KEY   =  1,
    00056     PGPTAG_SIGNATURE            =  2,
    00057     PGPTAG_SYMMETRIC_SESSION_KEY=  3,
    00058     PGPTAG_ONEPASS_SIGNATURE    =  4,
    00059     PGPTAG_SECRET_KEY           =  5,
    00060     PGPTAG_PUBLIC_KEY           =  6,
    00061     PGPTAG_SECRET_SUBKEY        =  7,
    00062     PGPTAG_COMPRESSED_DATA      =  8,
    00063     PGPTAG_SYMMETRIC_DATA       =  9,
    00064     PGPTAG_MARKER               = 10,
    00065     PGPTAG_LITERAL_DATA         = 11,
    00066     PGPTAG_TRUST                = 12,
    00067     PGPTAG_USER_ID              = 13,
    00068     PGPTAG_PUBLIC_SUBKEY        = 14,
    00069     PGPTAG_COMMENT_OLD          = 16,
    00070     PGPTAG_PHOTOID              = 17,
    00071     PGPTAG_ENCRYPTED_MDC        = 18,
    00072     PGPTAG_MDC                  = 19,
    00073     PGPTAG_PRIVATE_60           = 60,
    00074     PGPTAG_COMMENT              = 61,
    00075     PGPTAG_PRIVATE_62           = 62,
    00076     PGPTAG_CONTROL              = 63
    00077 } pgpTag;
    00078
    00113 typedef struct pgpPktPubkey_s {
    00114     uint8_t version;
    00115     pgpKeyID_t keyid;
    00116     uint8_t algo;
    00117 } pgpPktPubkey;
    00118
    00119
    00126 typedef enum pgpSigType_e {
    00127     PGPSIGTYPE_BINARY            = 0x00,
    00128     PGPSIGTYPE_TEXT              = 0x01,
    00129     PGPSIGTYPE_STANDALONE        = 0x02,
    00130     PGPSIGTYPE_GENERIC_CERT      = 0x10,
    00132     PGPSIGTYPE_PERSONA_CERT      = 0x11,
    00134     PGPSIGTYPE_CASUAL_CERT       = 0x12,
    00136     PGPSIGTYPE_POSITIVE_CERT     = 0x13,
    00138     PGPSIGTYPE_SUBKEY_BINDING    = 0x18,
    00139     PGPSIGTYPE_SIGNED_KEY        = 0x1F,
    00140     PGPSIGTYPE_KEY_REVOKE        = 0x20,
    00141     PGPSIGTYPE_SUBKEY_REVOKE     = 0x28,
    00142     PGPSIGTYPE_CERT_REVOKE       = 0x30,
    00143     PGPSIGTYPE_TIMESTAMP         = 0x40
    00144 } pgpSigType;
    00145
    00169 typedef enum pgpPubkeyAlgo_e {
    00170     PGPPUBKEYALGO_RSA           =  1,
    00171     PGPPUBKEYALGO_RSA_ENCRYPT   =  2,
    00172     PGPPUBKEYALGO_RSA_SIGN      =  3,
    00173     PGPPUBKEYALGO_ELGAMAL_ENCRYPT = 16,
    00174     PGPPUBKEYALGO_DSA           = 17,
    00175     PGPPUBKEYALGO_EC            = 18,
    00176     PGPPUBKEYALGO_ECDSA         = 19,
    00177     PGPPUBKEYALGO_ELGAMAL       = 20,
    00178     PGPPUBKEYALGO_DH            = 21
    00179 } pgpPubkeyAlgo;
    00180
    00205 typedef enum pgpSymkeyAlgo_e {
    00206     PGPSYMKEYALGO_PLAINTEXT     =  0,
    00207     PGPSYMKEYALGO_IDEA          =  1,
    00208     PGPSYMKEYALGO_TRIPLE_DES    =  2,
    00209     PGPSYMKEYALGO_CAST5         =  3,
    00210     PGPSYMKEYALGO_BLOWFISH      =  4,
    00211     PGPSYMKEYALGO_SAFER         =  5,
    00212     PGPSYMKEYALGO_DES_SK        =  6,
    00213     PGPSYMKEYALGO_AES_128       =  7,
    00214     PGPSYMKEYALGO_AES_192       =  8,
    00215     PGPSYMKEYALGO_AES_256       =  9,
    00216     PGPSYMKEYALGO_TWOFISH       = 10,
    00217     PGPSYMKEYALGO_NOENCRYPT     = 110
    00218 } pgpSymkeyAlgo;
    00219
    00235 typedef enum pgpCompressAlgo_e {
    00236     PGPCOMPRESSALGO_NONE        =  0,
    00237     PGPCOMPRESSALGO_ZIP         =  1,
    00238     PGPCOMPRESSALGO_ZLIB        =  2,
    00239     PGPCOMPRESSALGO_BZIP2       =  3
    00240 } pgpCompressAlgo;
    00241
    00263 typedef enum pgpHashAlgo_e {
    00264     PGPHASHALGO_MD5             =  1,
    00265     PGPHASHALGO_SHA1            =  2,
    00266     PGPHASHALGO_RIPEMD160       =  3,
    00267     PGPHASHALGO_MD2             =  5,
    00268     PGPHASHALGO_TIGER192        =  6,
    00269     PGPHASHALGO_HAVAL_5_160     =  7,
    00270     PGPHASHALGO_SHA256          =  8,
    00271     PGPHASHALGO_SHA384          =  9,
    00272     PGPHASHALGO_SHA512          = 10,
    00273 } pgpHashAlgo;
    00274
    00296 typedef struct pgpPktSigV3_s {
    00297     uint8_t version;
    00298     uint8_t hashlen;
    00299     uint8_t sigtype;
    00300     pgpTime_t time;
    00301     pgpKeyID_t signid;
    00302     uint8_t pubkey_algo;
    00303     uint8_t hash_algo;
    00304     uint8_t signhash16[2];
    00305 } * pgpPktSigV3;
    00306
    00328 typedef struct pgpPktSigV4_s {
    00329     uint8_t version;
    00330     uint8_t sigtype;
    00331     uint8_t pubkey_algo;
    00332     uint8_t hash_algo;
    00333     uint8_t hashlen[2];
    00334 } * pgpPktSigV4;
    00335
    00402 typedef enum pgpSubType_e {
    00403     PGPSUBTYPE_NONE             =   0,
    00404     PGPSUBTYPE_SIG_CREATE_TIME  =   2,
    00405     PGPSUBTYPE_SIG_EXPIRE_TIME  =   3,
    00406     PGPSUBTYPE_EXPORTABLE_CERT  =   4,
    00407     PGPSUBTYPE_TRUST_SIG        =   5,
    00408     PGPSUBTYPE_REGEX            =   6,
    00409     PGPSUBTYPE_REVOCABLE        =   7,
    00410     PGPSUBTYPE_KEY_EXPIRE_TIME  =   9,
    00411     PGPSUBTYPE_ARR              =  10,
    00412     PGPSUBTYPE_PREFER_SYMKEY    =  11,
    00413     PGPSUBTYPE_REVOKE_KEY       =  12,
    00414     PGPSUBTYPE_ISSUER_KEYID     =  16,
    00415     PGPSUBTYPE_NOTATION         =  20,
    00416     PGPSUBTYPE_PREFER_HASH      =  21,
    00417     PGPSUBTYPE_PREFER_COMPRESS  =  22,
    00418     PGPSUBTYPE_KEYSERVER_PREFERS=  23,
    00419     PGPSUBTYPE_PREFER_KEYSERVER =  24,
    00420     PGPSUBTYPE_PRIMARY_USERID   =  25,
    00421     PGPSUBTYPE_POLICY_URL       =  26,
    00422     PGPSUBTYPE_KEY_FLAGS        =  27,
    00423     PGPSUBTYPE_SIGNER_USERID    =  28,
    00424     PGPSUBTYPE_REVOKE_REASON    =  29,
    00425     PGPSUBTYPE_FEATURES         =  30,
    00426     PGPSUBTYPE_EMBEDDED_SIG     =  32,
    00428     PGPSUBTYPE_INTERNAL_100     = 100,
    00429     PGPSUBTYPE_INTERNAL_101     = 101,
    00430     PGPSUBTYPE_INTERNAL_102     = 102,
    00431     PGPSUBTYPE_INTERNAL_103     = 103,
    00432     PGPSUBTYPE_INTERNAL_104     = 104,
    00433     PGPSUBTYPE_INTERNAL_105     = 105,
    00434     PGPSUBTYPE_INTERNAL_106     = 106,
    00435     PGPSUBTYPE_INTERNAL_107     = 107,
    00436     PGPSUBTYPE_INTERNAL_108     = 108,
    00437     PGPSUBTYPE_INTERNAL_109     = 109,
    00438     PGPSUBTYPE_INTERNAL_110     = 110,
    00440     PGPSUBTYPE_CRITICAL         = 128
    00441 } pgpSubType;
    00442
    00463 typedef union pgpPktSig_u {
    00464     struct pgpPktSigV3_s v3;
    00465     struct pgpPktSigV4_s v4;
    00466 } * pgpPktSig;
    00467
    00496 typedef struct pgpPktSymkey_s {
    00497     uint8_t version;
    00498     uint8_t symkey_algo;
    00499     uint8_t s2k[1];
    00500 } pgpPktSymkey;
    00501
    00531 typedef struct pgpPktOnepass_s {
    00532     uint8_t version;
    00533     uint8_t sigtype;
    00534     uint8_t hash_algo;
    00535     uint8_t pubkey_algo;
    00536     pgpKeyID_t signid;
    00537     uint8_t nested;
    00538 } * pgpPktOnepass;
    00539
    00612 typedef struct pgpPktKeyV3_s {
    00613     uint8_t version;
    00614     pgpTime_t time;
    00615     uint8_t valid[2];
    00616     uint8_t pubkey_algo;
    00617 } * pgpPktKeyV3;
    00618
    00650 typedef struct pgpPktKeyV4_s {
    00651     uint8_t version;
    00652     pgpTime_t time;
    00653     uint8_t pubkey_algo;
    00654 } * pgpPktKeyV4;
    00655
    00720 typedef union pgpPktKey_u {
    00721     struct pgpPktKeyV3_s v3;
    00722     struct pgpPktKeyV4_s v4;
    00723 } pgpPktKey;
    00724
    00725 /* \ingroup rpmpgp
    00726  * 5.6. Compressed Data Packet (Tag 8)
    00727  *
    00728  * The Compressed Data packet contains compressed data. Typically, this
    00729  * packet is found as the contents of an encrypted packet, or following
    00730  * a Signature or One-Pass Signature packet, and contains literal data
    00731  * packets.
    00732  *
    00733  * The body of this packet consists of:
    00734  *   - One octet that gives the algorithm used to compress the packet.
    00735  *   - The remainder of the packet is compressed data.
    00736  *
    00737  * A Compressed Data Packet's body contains an block that compresses
    00738  * some set of packets. See section "Packet Composition" for details on
    00739  * how messages are formed.
    00740  *
    00741  * ZIP-compressed packets are compressed with raw RFC 1951 DEFLATE
    00742  * blocks. Note that PGP V2.6 uses 13 bits of compression. If an
    00743  * implementation uses more bits of compression, PGP V2.6 cannot
    00744  * decompress it.
    00745  *
    00746  * ZLIB-compressed packets are compressed with RFC 1950 ZLIB-style
    00747  * blocks.
    00748  */
    00749 typedef struct pgpPktCdata_s {
    00750     uint8_t compressalgo;
    00751     uint8_t data[1];
    00752 } pgpPktCdata;
    00753
    00754 /* \ingroup rpmpgp
    00755  * 5.7. Symmetrically Encrypted Data Packet (Tag 9)
    00756  *
    00757  * The Symmetrically Encrypted Data packet contains data encrypted with
    00758  * a symmetric-key algorithm. When it has been decrypted, it will
    00759  * typically contain other packets (often literal data packets or
    00760  * compressed data packets).
    00761  *
    00762  * The body of this packet consists of:
    00763  *   - Encrypted data, the output of the selected symmetric-key cipher
    00764  *     operating in PGP's variant of Cipher Feedback (CFB) mode.
    00765  *
    00766  * The symmetric cipher used may be specified in an Public-Key or
    00767  * Symmetric-Key Encrypted Session Key packet that precedes the
    00768  * Symmetrically Encrypted Data Packet.  In that case, the cipher
    00769  * algorithm octet is prefixed to the session key before it is
    00770  * encrypted.  If no packets of these types precede the encrypted data,
    00771  * the IDEA algorithm is used with the session key calculated as the MD5
    00772  * hash of the passphrase.
    00773  *
    00774  * The data is encrypted in CFB mode, with a CFB shift size equal to the
    00775  * cipher's block size.  The Initial Vector (IV) is specified as all
    00776  * zeros.  Instead of using an IV, OpenPGP prefixes a 10-octet string to
    00777  * the data before it is encrypted.  The first eight octets are random,
    00778  * and the 9th and 10th octets are copies of the 7th and 8th octets,
    00779  * respectively. After encrypting the first 10 octets, the CFB state is
    00780  * resynchronized if the cipher block size is 8 octets or less.  The
    00781  * last 8 octets of ciphertext are passed through the cipher and the
    00782  * block boundary is reset.
    00783  *
    00784  * The repetition of 16 bits in the 80 bits of random data prefixed to
    00785  * the message allows the receiver to immediately check whether the
    00786  * session key is incorrect.
    00787  */
    00788 typedef struct pgpPktEdata_s {
    00789     uint8_t data[1];
    00790 } pgpPktEdata;
    00791
    00792 /* \ingroup rpmpgp
    00793  * 5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)
    00794  *
    00795  * An experimental version of PGP used this packet as the Literal
    00796  * packet, but no released version of PGP generated Literal packets with
    00797  * this tag. With PGP 5.x, this packet has been re-assigned and is
    00798  * reserved for use as the Marker packet.
    00799  *
    00800  * The body of this packet consists of:
    00801  *   - The three octets 0x50, 0x47, 0x50 (which spell "PGP" in UTF-8).
    00802  *
    00803  * Such a packet MUST be ignored when received.  It may be placed at the
    00804  * beginning of a message that uses features not available in PGP 2.6.x
    00805  * in order to cause that version to report that newer software is
    00806  * necessary to process the message.
    00807  */
    00808 /* \ingroup rpmpgp
    00809  * 5.9. Literal Data Packet (Tag 11)
    00810  *
    00811  * A Literal Data packet contains the body of a message; data that is
    00812  * not to be further interpreted.
    00813  *
    00814  * The body of this packet consists of:
    00815  *   - A one-octet field that describes how the data is formatted.
    00816  *
    00817  * If it is a 'b' (0x62), then the literal packet contains binary data.
    00818  * If it is a 't' (0x74), then it contains text data, and thus may need
    00819  * line ends converted to local form, or other text-mode changes.  RFC
    00820  * 1991 also defined a value of 'l' as a 'local' mode for machine-local
    00821  * conversions.  This use is now deprecated.
    00822  *   - File name as a string (one-octet length, followed by file name),
    00823  *     if the encrypted data should be saved as a file.
    00824  *
    00825  * If the special name "_CONSOLE" is used, the message is considered to
    00826  * be "for your eyes only".  This advises that the message data is
    00827  * unusually sensitive, and the receiving program should process it more
    00828  * carefully, perhaps avoiding storing the received data to disk, for
    00829  * example.
    00830  *   - A four-octet number that indicates the modification date of the
    00831  *     file, or the creation time of the packet, or a zero that
    00832  *     indicates the present time.
    00833  *   - The remainder of the packet is literal data.
    00834  *
    00835  * Text data is stored with <CR><LF> text endings (i.e. network-normal
    00836  * line endings).  These should be converted to native line endings by
    00837  * the receiving software.
    00838  */
    00839 typedef struct pgpPktLdata_s {
    00840     uint8_t format;
    00841     uint8_t filenamelen;
    00842     uint8_t filename[1];
    00843 } pgpPktLdata;
    00844
    00845 /* \ingroup rpmpgp
    00846  * 5.10. Trust Packet (Tag 12)
    00847  *
    00848  * The Trust packet is used only within keyrings and is not normally
    00849  * exported.  Trust packets contain data that record the user's
    00850  * specifications of which key holders are trustworthy introducers,
    00851  * along with other information that implementing software uses for
    00852  * trust information.
    00853  *
    00854  * Trust packets SHOULD NOT be emitted to output streams that are
    00855  * transferred to other users, and they SHOULD be ignored on any input
    00856  * other than local keyring files.
    00857  */
    00858 typedef struct pgpPktTrust_s {
    00859     uint8_t flag;
    00860 } pgpPktTrust;
    00861
    00862 /* \ingroup rpmpgp
    00863  * 5.11. User ID Packet (Tag 13)
    00864  *
    00865  * A User ID packet consists of data that is intended to represent the
    00866  * name and email address of the key holder.  By convention, it includes
    00867  * an RFC 822 mail name, but there are no restrictions on its content.
    00868  * The packet length in the header specifies the length of the user id.
    00869  * If it is text, it is encoded in UTF-8.
    00870  *
    00871  */
    00872 typedef struct pgpPktUid_s {
    00873     uint8_t userid[1];
    00874 } pgpPktUid;
    00875
    00878 union pgpPktPre_u {
    00879     pgpPktPubkey pubkey;
    00880     pgpPktSig sig;
    00881     pgpPktSymkey symkey;
    00882     pgpPktOnepass onepass;
    00883     pgpPktKey key;
    00884     pgpPktCdata cdata;
    00885     pgpPktEdata edata;
    00887     pgpPktLdata ldata;
    00888     pgpPktTrust tdata;
    00889     pgpPktUid uid;
    00890 };
    00891
    00894 typedef enum pgpArmor_e {
    00895     PGPARMOR_ERR_CRC_CHECK              = -7,
    00896     PGPARMOR_ERR_BODY_DECODE            = -6,
    00897     PGPARMOR_ERR_CRC_DECODE             = -5,
    00898     PGPARMOR_ERR_NO_END_PGP             = -4,
    00899     PGPARMOR_ERR_UNKNOWN_PREAMBLE_TAG   = -3,
    00900     PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE     = -2,
    00901     PGPARMOR_ERR_NO_BEGIN_PGP           = -1,
    00902 #define PGPARMOR_ERROR  PGPARMOR_ERR_NO_BEGIN_PGP
    00903     PGPARMOR_NONE               =  0,
    00904     PGPARMOR_MESSAGE            =  1,
    00905     PGPARMOR_PUBKEY             =  2,
    00906     PGPARMOR_SIGNATURE          =  3,
    00907     PGPARMOR_SIGNED_MESSAGE     =  4,
    00908     PGPARMOR_FILE               =  5,
    00909     PGPARMOR_PRIVKEY            =  6,
    00910     PGPARMOR_SECKEY             =  7
    00911 } pgpArmor;
    00912
    00915 typedef enum pgpArmorKey_e {
    00916     PGPARMORKEY_VERSION         = 1,
    00917     PGPARMORKEY_COMMENT         = 2,
    00918     PGPARMORKEY_MESSAGEID       = 3,
    00919     PGPARMORKEY_HASH            = 4,
    00920     PGPARMORKEY_CHARSET         = 5
    00921 } pgpArmorKey;
    00922
    00923 typedef enum pgpValType_e {
    00924     PGPVAL_TAG                  = 1,
    00925     PGPVAL_ARMORBLOCK           = 2,
    00926     PGPVAL_ARMORKEY             = 3,
    00927     PGPVAL_SIGTYPE              = 4,
    00928     PGPVAL_SUBTYPE              = 5,
    00929     PGPVAL_PUBKEYALGO           = 6,
    00930     PGPVAL_SYMKEYALGO           = 7,
    00931     PGPVAL_COMPRESSALGO         = 8,
    00932     PGPVAL_HASHALGO             = 9,
    00933     PGPVAL_SERVERPREFS          = 10,
    00934 } pgpValType;
    00935
    00939 typedef enum rpmDigestFlags_e {
    00940     RPMDIGEST_NONE      = 0
    00941 } rpmDigestFlags;
    00942
    00949 const char * pgpValString(pgpValType type, uint8_t val);
    00950
    00957 static inline
    00958 unsigned int pgpGrab(const uint8_t *s, size_t nbytes)
    00959 {
    00960     size_t i = 0;
    00961     size_t nb = (nbytes <= sizeof(i) ? nbytes : sizeof(i));
    00962     while (nb--)
    00963         i = (i << 8) | *s++;
    00964     return i;
    00965 }
    00966
    00973 static inline
    00974 size_t pgpLen(const uint8_t *s, size_t * lenp)
    00975 {
    00976     if (*s < 192) {
    00977         (*lenp) = *s++;
    00978         return 1;
    00979     } else if (*s < 255) {
    00980         (*lenp) = ((((unsigned)s[0]) - 192) << 8) + s[1] + 192;
    00981         return 2;
    00982     } else {
    00983         (*lenp) = pgpGrab(s+1, (size_t) 4);
    00984         return 5;
    00985     }
    00986 }
    00987
    00994 char * pgpHexStr(const uint8_t *p, size_t plen);
    00995
    01004 int pgpPubkeyFingerprint(const uint8_t * pkt, size_t pktlen,
    01005                 pgpKeyID_t keyid);
    01006
    01014 int pgpExtractPubkeyFingerprint(const char * b64pkt, pgpKeyID_t keyid);
    01015
    01024 int pgpPrtPkts(const uint8_t *pkts, size_t pktlen, pgpDig dig, int printing);
    01025
    01033 pgpArmor pgpReadPkts(const char * fn, uint8_t ** pkt, size_t * pktlen);
    01034
    01042 pgpArmor pgpParsePkts(const char *armor, uint8_t ** pkt, size_t * pktlen);
    01043
    01051 char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns);
    01052
    01057 pgpDig pgpNewDig(void);
    01058
    01063 void pgpCleanDig(pgpDig dig);
    01064
    01070 pgpDig pgpFreeDig(pgpDig dig);
    01071
    01078 rpmRC pgpVerifySig(pgpDig dig, DIGEST_CTX hashctx);
    01079
    01085 char *pgpIdentItem(pgpDigParams digp);
    01086
    01094 int rpmInitCrypto(void);
    01095
    01099 int rpmFreeCrypto(void);
    01100
    01106 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx);
    01107
    01113 size_t rpmDigestLength(pgpHashAlgo hashalgo);
    01114
    01122 DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags);
    01123
    01131 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len);
    01132
    01144 int rpmDigestFinal(DIGEST_CTX ctx,
    01145         void ** datap,
    01146         size_t * lenp, int asAscii);
    01147
    01152 rpmDigestBundle rpmDigestBundleNew(void);
    01153
    01159 rpmDigestBundle rpmDigestBundleFree(rpmDigestBundle bundle);
    01160
    01168 int rpmDigestBundleAdd(rpmDigestBundle bundle, pgpHashAlgo algo,
    01169                         rpmDigestFlags flags);
    01170
    01178 int rpmDigestBundleUpdate(rpmDigestBundle bundle, const void *data, size_t len);
    01179
    01190 int rpmDigestBundleFinal(rpmDigestBundle bundle,
    01191          pgpHashAlgo algo, void ** datap, size_t * lenp, int asAscii);
    01192
    01199 DIGEST_CTX rpmDigestBundleDupCtx(rpmDigestBundle bundle, pgpHashAlgo algo);
    01200
    01201 #ifdef __cplusplus
    01202 }
    01203 #endif
    01204
    01205 #endif  /* H_RPMPGP */