Blame


1 6e527fbc 2005-02-13 devnull #include "std.h"
2 6e527fbc 2005-02-13 devnull #include "dat.h"
3 6e527fbc 2005-02-13 devnull
4 6e527fbc 2005-02-13 devnull /*
5 6e527fbc 2005-02-13 devnull * PKCS #1 v2.0 signatures (aka RSASSA-PKCS1-V1_5)
6 6e527fbc 2005-02-13 devnull *
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.
9 6e527fbc 2005-02-13 devnull *
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.
12 6e527fbc 2005-02-13 devnull *
13 6e527fbc 2005-02-13 devnull * We sign hashes of messages instead of the messages
14 6e527fbc 2005-02-13 devnull * themselves.
15 6e527fbc 2005-02-13 devnull *
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.
19 6e527fbc 2005-02-13 devnull */
20 6e527fbc 2005-02-13 devnull
21 6e527fbc 2005-02-13 devnull static int mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen);
22 6e527fbc 2005-02-13 devnull
23 6e527fbc 2005-02-13 devnull int
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)
26 6e527fbc 2005-02-13 devnull {
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;
30 6e527fbc 2005-02-13 devnull
31 6e527fbc 2005-02-13 devnull /*
32 6e527fbc 2005-02-13 devnull * Create ASN.1
33 6e527fbc 2005-02-13 devnull */
34 6e527fbc 2005-02-13 devnull n = mkasn1(asn1, hash, digest, dlen);
35 6e527fbc 2005-02-13 devnull
36 6e527fbc 2005-02-13 devnull /*
37 6e527fbc 2005-02-13 devnull * Create number to sign.
38 6e527fbc 2005-02-13 devnull */
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;
43 6e527fbc 2005-02-13 devnull }
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;
48 6e527fbc 2005-02-13 devnull }
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;
60 6e527fbc 2005-02-13 devnull
61 6e527fbc 2005-02-13 devnull /*
62 6e527fbc 2005-02-13 devnull * Sign it.
63 6e527fbc 2005-02-13 devnull */
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;
71 6e527fbc 2005-02-13 devnull }
72 6e527fbc 2005-02-13 devnull
73 ce94dbe6 2005-02-13 devnull int
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)
76 ce94dbe6 2005-02-13 devnull {
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;
80 ce94dbe6 2005-02-13 devnull
81 ce94dbe6 2005-02-13 devnull /*
82 ce94dbe6 2005-02-13 devnull * Create ASN.1
83 ce94dbe6 2005-02-13 devnull */
84 ce94dbe6 2005-02-13 devnull n = mkasn1(asn1, hash, digest, dlen);
85 ce94dbe6 2005-02-13 devnull
86 ce94dbe6 2005-02-13 devnull /*
87 ce94dbe6 2005-02-13 devnull * Extract plaintext of signature.
88 ce94dbe6 2005-02-13 devnull */
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;
101 ce94dbe6 2005-02-13 devnull }
102 ce94dbe6 2005-02-13 devnull return 0;
103 ce94dbe6 2005-02-13 devnull }
104 ce94dbe6 2005-02-13 devnull
105 6e527fbc 2005-02-13 devnull /*
106 6e527fbc 2005-02-13 devnull * Mptobe but shift right to fill buffer.
107 6e527fbc 2005-02-13 devnull */
108 6e527fbc 2005-02-13 devnull void
109 6e527fbc 2005-02-13 devnull mptoberjust(mpint *b, uchar *buf, uint len)
110 6e527fbc 2005-02-13 devnull {
111 6e527fbc 2005-02-13 devnull int n;
112 6e527fbc 2005-02-13 devnull
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);
119 6e527fbc 2005-02-13 devnull }
120 6e527fbc 2005-02-13 devnull }
121 6e527fbc 2005-02-13 devnull
122 6e527fbc 2005-02-13 devnull /*
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.
126 6e527fbc 2005-02-13 devnull */
127 6e527fbc 2005-02-13 devnull
128 6e527fbc 2005-02-13 devnull /*
129 6e527fbc 2005-02-13 devnull * Hash OIDs
130 6e527fbc 2005-02-13 devnull *
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
133 6e527fbc 2005-02-13 devnull */
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 6e527fbc 2005-02-13 devnull ((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 };
145 6e527fbc 2005-02-13 devnull
146 6e527fbc 2005-02-13 devnull /*
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
150 6e527fbc 2005-02-13 devnull * }
151 ce94dbe6 2005-02-13 devnull *
152 ce94dbe6 2005-02-13 devnull * except that OpenSSL seems to sign
153 ce94dbe6 2005-02-13 devnull *
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
157 ce94dbe6 2005-02-13 devnull * }
158 ce94dbe6 2005-02-13 devnull *
159 ce94dbe6 2005-02-13 devnull * instead. Sigh.
160 6e527fbc 2005-02-13 devnull */
161 6e527fbc 2005-02-13 devnull static int
162 6e527fbc 2005-02-13 devnull mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen)
163 6e527fbc 2005-02-13 devnull {
164 6e527fbc 2005-02-13 devnull uchar *obj, *p;
165 6e527fbc 2005-02-13 devnull uint olen;
166 6e527fbc 2005-02-13 devnull
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);
173 6e527fbc 2005-02-13 devnull }else{
174 6e527fbc 2005-02-13 devnull sysfatal("bad alg in mkasn1");
175 6e527fbc 2005-02-13 devnull return -1;
176 6e527fbc 2005-02-13 devnull }
177 6e527fbc 2005-02-13 devnull
178 6e527fbc 2005-02-13 devnull p = asn1;
179 6e527fbc 2005-02-13 devnull *p++ = 0x30; /* sequence */
180 6e527fbc 2005-02-13 devnull p++;
181 6e527fbc 2005-02-13 devnull
182 ce94dbe6 2005-02-13 devnull *p++ = 0x30; /* another sequence */
183 ce94dbe6 2005-02-13 devnull p++;
184 ce94dbe6 2005-02-13 devnull
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;
189 6e527fbc 2005-02-13 devnull
190 ce94dbe6 2005-02-13 devnull *p++ = 0x05; /* null */
191 ce94dbe6 2005-02-13 devnull *p++ = 0;
192 ce94dbe6 2005-02-13 devnull
193 ce94dbe6 2005-02-13 devnull asn1[3] = p - (asn1+4); /* end of inner sequence */
194 ce94dbe6 2005-02-13 devnull
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;
199 6e527fbc 2005-02-13 devnull
200 ce94dbe6 2005-02-13 devnull asn1[1] = p - (asn1+2); /* end of outer sequence */
201 6e527fbc 2005-02-13 devnull return p-asn1;
202 6e527fbc 2005-02-13 devnull }
203 6e527fbc 2005-02-13 devnull