1 6e527fbc 2005-02-13 devnull #include "std.h"
2 6e527fbc 2005-02-13 devnull #include "dat.h"
5 6e527fbc 2005-02-13 devnull * PKCS #1 v2.0 signatures (aka RSASSA-PKCS1-V1_5)
7 6e527fbc 2005-02-13 devnull * You don't want to read the spec.
8 6e527fbc 2005-02-13 devnull * Here is what you need to know.
10 6e527fbc 2005-02-13 devnull * RSA sign (aka RSASP1) is just an RSA encryption.
11 6e527fbc 2005-02-13 devnull * RSA verify (aka RSAVP1) is just an RSA decryption.
13 6e527fbc 2005-02-13 devnull * We sign hashes of messages instead of the messages
14 6e527fbc 2005-02-13 devnull * themselves.
16 6e527fbc 2005-02-13 devnull * The hashes are encoded in ASN.1 DER to identify
17 6e527fbc 2005-02-13 devnull * the signature type, and then prefixed with 0x01 PAD 0x00
18 6e527fbc 2005-02-13 devnull * where PAD is as many 0xFF bytes as desired.
21 6e527fbc 2005-02-13 devnull static int mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen);
24 6e527fbc 2005-02-13 devnull rsasign(RSApriv *key, DigestAlg *hash, uchar *digest, uint dlen,
25 6e527fbc 2005-02-13 devnull uchar *sig, uint siglen)
27 6e527fbc 2005-02-13 devnull uchar asn1[64], *buf;
28 6e527fbc 2005-02-13 devnull int n, len, pad;
29 6e527fbc 2005-02-13 devnull mpint *m, *s;
32 6e527fbc 2005-02-13 devnull * Create ASN.1
34 6e527fbc 2005-02-13 devnull n = mkasn1(asn1, hash, digest, dlen);
37 6e527fbc 2005-02-13 devnull * Create number to sign.
39 ce94dbe6 2005-02-13 devnull len = (mpsignif(key->pub.n)+7)/8 - 1;
40 6e527fbc 2005-02-13 devnull if(len < n+2){
41 6e527fbc 2005-02-13 devnull werrstr("rsa key too short");
42 6e527fbc 2005-02-13 devnull return -1;
44 6e527fbc 2005-02-13 devnull pad = len - (n+2);
45 6e527fbc 2005-02-13 devnull if(siglen < len){
46 6e527fbc 2005-02-13 devnull werrstr("signature buffer too short");
47 6e527fbc 2005-02-13 devnull return -1;
49 6e527fbc 2005-02-13 devnull buf = malloc(len);
50 6e527fbc 2005-02-13 devnull if(buf == nil)
51 6e527fbc 2005-02-13 devnull return -1;
52 6e527fbc 2005-02-13 devnull buf[0] = 0x01;
53 6e527fbc 2005-02-13 devnull memset(buf+1, 0xFF, pad);
54 6e527fbc 2005-02-13 devnull buf[1+pad] = 0x00;
55 6e527fbc 2005-02-13 devnull memmove(buf+1+pad+1, asn1, n);
56 6e527fbc 2005-02-13 devnull m = betomp(buf, len, nil);
57 6e527fbc 2005-02-13 devnull free(buf);
58 6e527fbc 2005-02-13 devnull if(m == nil)
59 6e527fbc 2005-02-13 devnull return -1;
62 6e527fbc 2005-02-13 devnull * Sign it.
64 6e527fbc 2005-02-13 devnull s = rsadecrypt(key, m, nil);
65 6e527fbc 2005-02-13 devnull mpfree(m);
66 6e527fbc 2005-02-13 devnull if(s == nil)
67 6e527fbc 2005-02-13 devnull return -1;
68 ce94dbe6 2005-02-13 devnull mptoberjust(s, sig, len+1);
69 6e527fbc 2005-02-13 devnull mpfree(s);
70 ce94dbe6 2005-02-13 devnull return len+1;
74 ce94dbe6 2005-02-13 devnull rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen,
75 ce94dbe6 2005-02-13 devnull uchar *sig, uint siglen)
77 ce94dbe6 2005-02-13 devnull uchar asn1[64], xasn1[64];
78 ce94dbe6 2005-02-13 devnull int n, nn;
79 ce94dbe6 2005-02-13 devnull mpint *m, *s;
82 ce94dbe6 2005-02-13 devnull * Create ASN.1
84 ce94dbe6 2005-02-13 devnull n = mkasn1(asn1, hash, digest, dlen);
87 ce94dbe6 2005-02-13 devnull * Extract plaintext of signature.
89 ce94dbe6 2005-02-13 devnull s = betomp(sig, siglen, nil);
90 ce94dbe6 2005-02-13 devnull if(s == nil)
91 ce94dbe6 2005-02-13 devnull return -1;
92 ce94dbe6 2005-02-13 devnull m = rsaencrypt(key, s, nil);
93 ce94dbe6 2005-02-13 devnull mpfree(s);
94 ce94dbe6 2005-02-13 devnull if(m == nil)
95 ce94dbe6 2005-02-13 devnull return -1;
96 ce94dbe6 2005-02-13 devnull nn = mptobe(m, xasn1, sizeof xasn1, nil);
97 ce94dbe6 2005-02-13 devnull mpfree(m);
98 ce94dbe6 2005-02-13 devnull if(n != nn || memcmp(asn1, xasn1, n) != 0){
99 ce94dbe6 2005-02-13 devnull werrstr("signature did not verify");
100 ce94dbe6 2005-02-13 devnull return -1;
102 ce94dbe6 2005-02-13 devnull return 0;
106 6e527fbc 2005-02-13 devnull * Mptobe but shift right to fill buffer.
109 6e527fbc 2005-02-13 devnull mptoberjust(mpint *b, uchar *buf, uint len)
113 6e527fbc 2005-02-13 devnull n = mptobe(b, buf, len, nil);
114 6e527fbc 2005-02-13 devnull assert(n >= 0);
115 6e527fbc 2005-02-13 devnull if(n < len){
116 6e527fbc 2005-02-13 devnull len -= n;
117 6e527fbc 2005-02-13 devnull memmove(buf+len, buf, n);
118 6e527fbc 2005-02-13 devnull memset(buf, 0, len);
123 6e527fbc 2005-02-13 devnull * Simple ASN.1 encodings.
124 6e527fbc 2005-02-13 devnull * Lengths < 128 are encoded as 1-bytes constants,
125 6e527fbc 2005-02-13 devnull * making our life easy.
129 6e527fbc 2005-02-13 devnull * Hash OIDs
131 6e527fbc 2005-02-13 devnull * SHA1 = 1.3.14.3.2.26
132 6e527fbc 2005-02-13 devnull * MDx = 1.2.840.113549.2.x
134 6e527fbc 2005-02-13 devnull #define O0(a,b) ((a)*40+(b))
135 6e527fbc 2005-02-13 devnull #define O2(x) \
136 6e527fbc 2005-02-13 devnull (((x)>>7)&0x7F)|0x80, \
137 6e527fbc 2005-02-13 devnull ((x)&0x7F)
138 6e527fbc 2005-02-13 devnull #define O3(x) \
139 6e527fbc 2005-02-13 devnull (((x)>>14)&0x7F)|0x80, \
140 6e527fbc 2005-02-13 devnull (((x)>>7)&0x7F)|0x80, \
141 fa325e9b 2020-01-10 cross ((x)&0x7F)
142 6e527fbc 2005-02-13 devnull uchar oidsha1[] = { O0(1, 3), 14, 3, 2, 26 };
143 6e527fbc 2005-02-13 devnull uchar oidmd2[] = { O0(1, 2), O2(840), O3(113549), 2, 2 };
144 6e527fbc 2005-02-13 devnull uchar oidmd5[] = { O0(1, 2), O2(840), O3(113549), 2, 5 };
147 6e527fbc 2005-02-13 devnull * DigestInfo ::= SEQUENCE {
148 6e527fbc 2005-02-13 devnull * digestAlgorithm AlgorithmIdentifier,
149 6e527fbc 2005-02-13 devnull * digest OCTET STRING
152 ce94dbe6 2005-02-13 devnull * except that OpenSSL seems to sign
154 ce94dbe6 2005-02-13 devnull * DigestInfo ::= SEQUENCE {
155 ce94dbe6 2005-02-13 devnull * SEQUENCE{ digestAlgorithm AlgorithmIdentifier, NULL }
156 ce94dbe6 2005-02-13 devnull * digest OCTET STRING
159 ce94dbe6 2005-02-13 devnull * instead. Sigh.
161 6e527fbc 2005-02-13 devnull static int
162 6e527fbc 2005-02-13 devnull mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen)
164 6e527fbc 2005-02-13 devnull uchar *obj, *p;
165 6e527fbc 2005-02-13 devnull uint olen;
167 6e527fbc 2005-02-13 devnull if(alg == sha1){
168 6e527fbc 2005-02-13 devnull obj = oidsha1;
169 6e527fbc 2005-02-13 devnull olen = sizeof(oidsha1);
170 6e527fbc 2005-02-13 devnull }else if(alg == md5){
171 6e527fbc 2005-02-13 devnull obj = oidmd5;
172 6e527fbc 2005-02-13 devnull olen = sizeof(oidmd5);
174 6e527fbc 2005-02-13 devnull sysfatal("bad alg in mkasn1");
175 6e527fbc 2005-02-13 devnull return -1;
178 6e527fbc 2005-02-13 devnull p = asn1;
179 6e527fbc 2005-02-13 devnull *p++ = 0x30; /* sequence */
182 ce94dbe6 2005-02-13 devnull *p++ = 0x30; /* another sequence */
185 6e527fbc 2005-02-13 devnull *p++ = 0x06; /* object id */
186 6e527fbc 2005-02-13 devnull *p++ = olen;
187 6e527fbc 2005-02-13 devnull memmove(p, obj, olen);
188 6e527fbc 2005-02-13 devnull p += olen;
190 ce94dbe6 2005-02-13 devnull *p++ = 0x05; /* null */
191 ce94dbe6 2005-02-13 devnull *p++ = 0;
193 ce94dbe6 2005-02-13 devnull asn1[3] = p - (asn1+4); /* end of inner sequence */
195 6e527fbc 2005-02-13 devnull *p++ = 0x04; /* octet string */
196 6e527fbc 2005-02-13 devnull *p++ = dlen;
197 6e527fbc 2005-02-13 devnull memmove(p, d, dlen);
198 6e527fbc 2005-02-13 devnull p += dlen;
200 ce94dbe6 2005-02-13 devnull asn1[1] = p - (asn1+2); /* end of outer sequence */
201 6e527fbc 2005-02-13 devnull return p-asn1;