@@ -10,15 +10,16 @@ use pgp::armor::BlockType;
1010use pgp:: composed:: {
1111 ArmorOptions , DecryptionOptions , Deserializable , DetachedSignature , KeyType as PgpKeyType ,
1212 Message , MessageBuilder , SecretKeyParamsBuilder , SignedPublicKey , SignedPublicSubKey ,
13- SignedSecretKey , SubkeyParamsBuilder , TheRing ,
13+ SignedSecretKey , SubkeyParamsBuilder , SubpacketConfig , TheRing ,
1414} ;
1515use pgp:: crypto:: aead:: { AeadAlgorithm , ChunkSize } ;
1616use pgp:: crypto:: ecc_curve:: ECCCurve ;
1717use pgp:: crypto:: hash:: HashAlgorithm ;
1818use pgp:: crypto:: sym:: SymmetricKeyAlgorithm ;
1919use pgp:: packet:: { SignatureConfig , SignatureType , Subpacket , SubpacketData } ;
2020use pgp:: types:: {
21- CompressionAlgorithm , KeyDetails , Password , PublicKeyTrait , SecretKeyTrait as _, StringToKey ,
21+ CompressionAlgorithm , KeyDetails , KeyVersion , Password , PublicKeyTrait , SecretKeyTrait as _,
22+ StringToKey ,
2223} ;
2324use rand_old:: { Rng as _, thread_rng} ;
2425use tokio:: runtime:: Handle ;
@@ -190,6 +191,35 @@ pub async fn pk_encrypt(
190191 let pkeys = public_keys_for_encryption
191192 . iter ( )
192193 . filter_map ( select_pk_for_encryption) ;
194+ let subpkts = {
195+ let private_key_fp = private_key_for_signing. fingerprint ( ) ;
196+ let mut hashed = Vec :: with_capacity ( 1 + public_keys_for_encryption. len ( ) ) ;
197+ hashed. push ( Subpacket :: critical ( SubpacketData :: SignatureCreationTime (
198+ chrono:: Utc :: now ( ) . trunc_subsecs ( 0 ) ,
199+ ) ) ?) ;
200+ for key in & public_keys_for_encryption {
201+ let fp = key. fingerprint ( ) ;
202+ if fp == private_key_fp {
203+ continue ;
204+ }
205+ let data = SubpacketData :: IntendedRecipientFingerprint ( fp) ;
206+ let subpkt = match private_key_for_signing. version ( ) < KeyVersion :: V6 {
207+ true => Subpacket :: regular ( data) ?,
208+ false => Subpacket :: critical ( data) ?,
209+ } ;
210+ hashed. push ( subpkt) ;
211+ }
212+ hashed. push ( Subpacket :: regular ( SubpacketData :: IssuerFingerprint (
213+ private_key_fp,
214+ ) ) ?) ;
215+ let mut unhashed = vec ! [ ] ;
216+ if private_key_for_signing. version ( ) <= KeyVersion :: V4 {
217+ unhashed. push ( Subpacket :: regular ( SubpacketData :: Issuer (
218+ private_key_for_signing. key_id ( ) ,
219+ ) ) ?) ;
220+ }
221+ SubpacketConfig :: UserDefined { hashed, unhashed }
222+ } ;
193223
194224 let msg = MessageBuilder :: from_bytes ( "" , plain) ;
195225 let encoded_msg = match seipd_version {
@@ -205,7 +235,12 @@ pub async fn pk_encrypt(
205235 }
206236
207237 let hash_algorithm = private_key_for_signing. hash_alg ( ) ;
208- msg. sign ( & * private_key_for_signing, Password :: empty ( ) , hash_algorithm) ;
238+ msg. sign_with_subpackets (
239+ & * private_key_for_signing,
240+ Password :: empty ( ) ,
241+ hash_algorithm,
242+ subpkts,
243+ ) ;
209244 if compress {
210245 msg. compression ( CompressionAlgorithm :: ZLIB ) ;
211246 }
@@ -229,7 +264,12 @@ pub async fn pk_encrypt(
229264 }
230265
231266 let hash_algorithm = private_key_for_signing. hash_alg ( ) ;
232- msg. sign ( & * private_key_for_signing, Password :: empty ( ) , hash_algorithm) ;
267+ msg. sign_with_subpackets (
268+ & * private_key_for_signing,
269+ Password :: empty ( ) ,
270+ hash_algorithm,
271+ subpkts,
272+ ) ;
233273 if compress {
234274 msg. compression ( CompressionAlgorithm :: ZLIB ) ;
235275 }
@@ -264,9 +304,14 @@ pub fn pk_calc_signature(
264304 chrono:: Utc :: now( ) . trunc_subsecs( 0 ) ,
265305 ) ) ?,
266306 ] ;
267- config. unhashed_subpackets = vec ! [ Subpacket :: regular( SubpacketData :: Issuer (
268- private_key_for_signing. key_id( ) ,
269- ) ) ?] ;
307+ config. unhashed_subpackets = vec ! [ ] ;
308+ if private_key_for_signing. version ( ) <= KeyVersion :: V4 {
309+ config
310+ . unhashed_subpackets
311+ . push ( Subpacket :: regular ( SubpacketData :: Issuer (
312+ private_key_for_signing. key_id ( ) ,
313+ ) ) ?) ;
314+ }
270315
271316 let signature = config. sign (
272317 & private_key_for_signing. primary_key ,
@@ -634,8 +679,7 @@ mod tests {
634679 assert_eq ! ( content, CLEARTEXT ) ;
635680 assert_eq ! ( valid_signatures. len( ) , 1 ) ;
636681 for recipient_fps in valid_signatures. values ( ) {
637- // Intended Recipient Fingerprint subpackets aren't added currently.
638- assert_eq ! ( recipient_fps. len( ) , 0 ) ;
682+ assert_eq ! ( recipient_fps. len( ) , 1 ) ;
639683 }
640684
641685 // Check decrypting as Bob
@@ -650,7 +694,7 @@ mod tests {
650694 assert_eq ! ( content, CLEARTEXT ) ;
651695 assert_eq ! ( valid_signatures. len( ) , 1 ) ;
652696 for recipient_fps in valid_signatures. values ( ) {
653- assert_eq ! ( recipient_fps. len( ) , 0 ) ;
697+ assert_eq ! ( recipient_fps. len( ) , 1 ) ;
654698 }
655699 }
656700
0 commit comments