fix dsa patches: truncate hash
[epoint] / patches / sig.diff
1 diff -r 7ec969250bfc src/pkg/crypto/openpgp/packet/signature.go
2 --- a/src/pkg/crypto/openpgp/packet/signature.go        Tue Dec 27 09:49:19 2011 -0500
3 +++ b/src/pkg/crypto/openpgp/packet/signature.go        Sat Dec 31 02:23:37 2011 +0100
4 @@ -164,7 +164,7 @@
5  const (
6         creationTimeSubpacket        signatureSubpacketType = 2
7         signatureExpirationSubpacket signatureSubpacketType = 3
8 -       keyExpirySubpacket           signatureSubpacketType = 9
9 +       keyExpirationSubpacket       signatureSubpacketType = 9
10         prefSymmetricAlgosSubpacket  signatureSubpacketType = 11
11         issuerSubpacket              signatureSubpacketType = 16
12         prefHashAlgosSubpacket       signatureSubpacketType = 21
13 @@ -225,11 +225,7 @@
14                         return
15                 }
16                 t := binary.BigEndian.Uint32(subpacket)
17 -               if t == 0 {
18 -                       sig.CreationTime = time.Time{}
19 -               } else {
20 -                       sig.CreationTime = time.Unix(int64(t), 0)
21 -               }
22 +               sig.CreationTime = time.Unix(int64(t), 0)
23         case signatureExpirationSubpacket:
24                 // Signature expiration time, section 5.2.3.10
25                 if !isHashed {
26 @@ -241,7 +237,7 @@
27                 }
28                 sig.SigLifetimeSecs = new(uint32)
29                 *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
30 -       case keyExpirySubpacket:
31 +       case keyExpirationSubpacket:
32                 // Key expiration time, section 5.2.3.6
33                 if !isHashed {
34                         return
35 @@ -443,7 +439,14 @@
36                 sig.RSASignature.bytes, err = rsa.SignPKCS1v15(rand.Reader, priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
37                 sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
38         case PubKeyAlgoDSA:
39 -               r, s, err := dsa.Sign(rand.Reader, priv.PrivateKey.(*dsa.PrivateKey), digest)
40 +               dsaPrivateKey := priv.PrivateKey.(*dsa.PrivateKey)
41 +               // hash truncation according to FIPS 186-3 section 4.6
42 +               n := len(digest)
43 +               k := (dsaPrivateKey.Q.BitLen() + 7) / 8
44 +               if n > k {
45 +                       n = k
46 +               }
47 +               r, s, err := dsa.Sign(rand.Reader, dsaPrivateKey, digest[:n])
48                 if err == nil {
49                         sig.DSASigR.bytes = r.Bytes()
50                         sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
51 @@ -556,5 +559,59 @@
52                 subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
53         }
54  
55 +       if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
56 +               sigLifetime := make([]byte, 4)
57 +               binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
58 +               // signature expiration is marked as critical
59 +               subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
60 +       }
61 +
62 +       // The following subpackets may only appear in self-signatures
63 +
64 +       if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
65 +               keyLifetime := make([]byte, 4)
66 +               binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
67 +               // TODO:
68 +               // key expiration is marked as critical
69 +               subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
70 +       }
71 +
72 +       if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
73 +               subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
74 +       }
75 +
76 +       // []byte slices of preferred algorithms are not copied
77 +
78 +       if len(sig.PreferredSymmetric) > 0 {
79 +               subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
80 +       }
81 +
82 +       if len(sig.PreferredHash) > 0 {
83 +               subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
84 +       }
85 +
86 +       if len(sig.PreferredCompression) > 0 {
87 +               subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
88 +       }
89 +
90 +       // The Key Flags subpacket may only appear in self-signatures or certification signatures
91 +
92 +       if sig.FlagsValid {
93 +               flags := byte(0)
94 +               if sig.FlagCertify {
95 +                       flags |= 1
96 +               }
97 +               if sig.FlagSign {
98 +                       flags |= 2
99 +               }
100 +               if sig.FlagEncryptCommunications {
101 +                       flags |= 4
102 +               }
103 +               if sig.FlagEncryptStorage {
104 +                       flags |= 8
105 +               }
106 +               subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
107 +       }
108 +
109         return
110  }