5 * PKCS #1 v2.0 signatures (aka RSASSA-PKCS1-V1_5)
7 * You don't want to read the spec.
8 * Here is what you need to know.
10 * RSA sign (aka RSASP1) is just an RSA encryption.
11 * RSA verify (aka RSAVP1) is just an RSA decryption.
13 * We sign hashes of messages instead of the messages
16 * The hashes are encoded in ASN.1 DER to identify
17 * the signature type, and then prefixed with 0x01 PAD 0x00
18 * where PAD is as many 0xFF bytes as desired.
21 static int mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen);
24 rsasign(RSApriv *key, DigestAlg *hash, uchar *digest, uint dlen,
25 uchar *sig, uint siglen)
34 n = mkasn1(asn1, hash, digest, dlen);
37 * Create number to sign.
39 len = (mpsignif(key->pub.n)+7)/8 - 1;
41 werrstr("rsa key too short");
46 werrstr("signature buffer too short");
53 memset(buf+1, 0xFF, pad);
55 memmove(buf+1+pad+1, asn1, n);
56 m = betomp(buf, len, nil);
64 s = rsadecrypt(key, m, nil);
68 mptoberjust(s, sig, len+1);
74 rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen,
75 uchar *sig, uint siglen)
77 uchar asn1[64], xasn1[64];
84 n = mkasn1(asn1, hash, digest, dlen);
87 * Extract plaintext of signature.
89 s = betomp(sig, siglen, nil);
92 m = rsaencrypt(key, s, nil);
96 nn = mptobe(m, xasn1, sizeof xasn1, nil);
98 if(n != nn || memcmp(asn1, xasn1, n) != 0){
99 werrstr("signature did not verify");
106 * Mptobe but shift right to fill buffer.
109 mptoberjust(mpint *b, uchar *buf, uint len)
113 n = mptobe(b, buf, len, nil);
117 memmove(buf+len, buf, n);
123 * Simple ASN.1 encodings.
124 * Lengths < 128 are encoded as 1-bytes constants,
125 * making our life easy.
131 * SHA1 = 1.3.14.3.2.26
132 * MDx = 1.2.840.113549.2.x
134 #define O0(a,b) ((a)*40+(b))
136 (((x)>>7)&0x7F)|0x80, \
139 (((x)>>14)&0x7F)|0x80, \
140 (((x)>>7)&0x7F)|0x80, \
142 uchar oidsha1[] = { O0(1, 3), 14, 3, 2, 26 };
143 uchar oidmd2[] = { O0(1, 2), O2(840), O3(113549), 2, 2 };
144 uchar oidmd5[] = { O0(1, 2), O2(840), O3(113549), 2, 5 };
147 * DigestInfo ::= SEQUENCE {
148 * digestAlgorithm AlgorithmIdentifier,
149 * digest OCTET STRING
152 * except that OpenSSL seems to sign
154 * DigestInfo ::= SEQUENCE {
155 * SEQUENCE{ digestAlgorithm AlgorithmIdentifier, NULL }
156 * digest OCTET STRING
162 mkasn1(uchar *asn1, DigestAlg *alg, uchar *d, uint dlen)
169 olen = sizeof(oidsha1);
170 }else if(alg == md5){
172 olen = sizeof(oidmd5);
174 sysfatal("bad alg in mkasn1");
179 *p++ = 0x30; /* sequence */
182 *p++ = 0x30; /* another sequence */
185 *p++ = 0x06; /* object id */
187 memmove(p, obj, olen);
190 *p++ = 0x05; /* null */
193 asn1[3] = p - (asn1+4); /* end of inner sequence */
195 *p++ = 0x04; /* octet string */
200 asn1[1] = p - (asn1+2); /* end of outer sequence */