1 /*
2  * Copyright (c) 2004 Beeyond Software Holding BV
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 
23 #include "beecrypt/c++/adapter.h"
24 #include "beecrypt/c++/lang/NullPointerException.h"
25 using beecrypt::lang::NullPointerException;
26 #include "beecrypt/c++/provider/SHA1withDSASignature.h"
27 #include "beecrypt/c++/security/interfaces/DSAPrivateKey.h"
28 using beecrypt::security::interfaces::DSAPrivateKey;
29 #include "beecrypt/c++/security/interfaces/DSAPublicKey.h"
30 using beecrypt::security::interfaces::DSAPublicKey;
31 
32 namespace {
33 	const byte TAG_SEQUENCE = 0x30;
34 	const byte TAG_INTEGER = 0x02;
35 
36 	typedef int asn1error;
37 
38 	const asn1error DER_NOT_ENOUGH_DATA = -1;
39 	const asn1error DER_IMPLICIT_TAG_LENGTH = -2;
40 	const asn1error DER_TAG_TOO_LONG = -3;
41 	const asn1error DER_FORMAT_ERROR = -4;
42 	const asn1error DER_CONVERSION_ERROR = -5;
43 
44 	/* compute the size of a DER length encoding */
asn1_der_length(int length)45 	int asn1_der_length(int length) throw ()
46 	{
47 		if (length < 0x80)
48 			return 1;
49 		if (length < 0x100)
50 			return 2;
51 		if (length < 0x10000)
52 			return 3;
53 		if (length < 0x1000000)
54 			return 4;
55 		else
56 			return 5;
57 	}
58 
asn1_der_length_of(const mpnumber & n)59 	int asn1_der_length_of(const mpnumber& n) throw ()
60 	{
61 		int sigbits = mpbits(n.size, n.data);
62 
63 		return ((sigbits + 7) >> 3) + (((sigbits & 7) == 0) ? 1 : 0);
64 	}
65 
asn1_der_length_of_rssig(const mpnumber & r,const mpnumber & s)66 	int asn1_der_length_of_rssig(const mpnumber& r, const mpnumber& s) throw ()
67 	{
68 		int intlen, seqlen = 0;
69 
70 		intlen = asn1_der_length_of(r);
71 
72 		seqlen += 1 + asn1_der_length(intlen) + intlen;
73 
74 		intlen = asn1_der_length_of(s);
75 
76 		seqlen += 1 + asn1_der_length(intlen) + intlen;
77 
78 		return 1 + asn1_der_length(seqlen) + seqlen;
79 	}
80 
asn1_der_encode_length(byte * data,int length)81 	int asn1_der_encode_length(byte* data, int length) throw ()
82 	{
83 		if (length < 0x80)
84 		{
85 			data[0] = (byte) length;
86 			return 1;
87 		}
88 		else if (length < 0x100)
89 		{
90 			data[0] = (byte) 0x81;
91 			data[1] = (byte) length;
92 			return 2;
93 		}
94 		else if (length < 0x10000)
95 		{
96 			data[0] = (byte) 0x82;
97 			data[1] = (byte) (length >> 8);
98 			data[2] = (byte) (length     );
99 			return 3;
100 		}
101 		else if (length < 0x1000000)
102 		{
103 			data[0] = (byte) 0x83;
104 			data[1] = (byte) (length >> 16);
105 			data[2] = (byte) (length >>  8);
106 			data[3] = (byte) (length      );
107 			return 4;
108 		}
109 		else
110 		{
111 			data[0] = (byte) 0x84;
112 			data[1] = (byte) (length >> 24);
113 			data[2] = (byte) (length >> 16);
114 			data[3] = (byte) (length >>  8);
115 			data[4] = (byte) (length      );
116 			return 5;
117 		}
118 	}
119 
asn1_der_decode_length(const byte * data,int size,int * length)120 	int asn1_der_decode_length(const byte* data, int size, int* length) throw (asn1error)
121 	{
122 		int length_bytes;
123 		byte tmp;
124 
125 		if (size == 0)
126 			throw DER_NOT_ENOUGH_DATA;
127 
128 		tmp = *(data++);
129 
130 		if (tmp < 0x80)
131 		{
132 			*length = tmp;
133 			length_bytes = 0;
134 		}
135 		else
136 		{
137 			byte length_bytes = tmp & 0x7f;
138 
139 			if (length_bytes == 0)
140 				throw DER_IMPLICIT_TAG_LENGTH;
141 
142 			if (length_bytes >= size)
143 				throw DER_NOT_ENOUGH_DATA;
144 
145 			if (length_bytes > sizeof(int))
146 				throw DER_TAG_TOO_LONG;
147 
148 			int temp = 0;
149 
150 			for (byte i = 0; i < length_bytes; i++)
151 			{
152 				tmp = *(data++);
153 				temp <<= 8;
154 				temp += tmp;
155 			}
156 
157 			*length = temp;
158 		}
159 		return 1 + length_bytes;
160 	}
161 
asn1_der_encode(byte * data,const mpnumber & n)162 	int asn1_der_encode(byte* data, const mpnumber& n) throw ()
163 	{
164 		int offset = 1, length = asn1_der_length_of(n);
165 
166 		data[0] = TAG_INTEGER;
167 
168 		offset += asn1_der_encode_length(data+offset, length);
169 
170 		i2osp(data+offset, length, n.data, n.size);
171 
172 		offset += length;
173 
174 		return offset;
175 	}
176 
asn1_der_decode(const byte * data,int size,mpnumber & n)177 	int asn1_der_decode(const byte* data, int size, mpnumber& n) throw (asn1error)
178 	{
179 		int length, offset = 1;
180 
181 		if (size < 2)
182 			throw DER_NOT_ENOUGH_DATA;
183 
184 		if (data[0] != TAG_INTEGER)
185 			throw DER_FORMAT_ERROR;
186 
187 		offset += asn1_der_decode_length(data+offset, size-offset, &length);
188 
189 		if (length > (size-offset))
190 			throw DER_NOT_ENOUGH_DATA;
191 
192 		if (mpnsetbin(&n, data+offset, length))
193 			throw DER_CONVERSION_ERROR;
194 
195 		offset += length;
196 
197 		return offset;
198 	}
199 
asn1_der_encode_rssig(byte * data,const mpnumber & r,const mpnumber & s)200 	int asn1_der_encode_rssig(byte* data, const mpnumber& r, const mpnumber& s) throw ()
201 	{
202 		int intlen, seqlen = 0;
203 
204 		intlen = asn1_der_length_of(r);
205 		seqlen += 1 + asn1_der_length(intlen) + intlen;
206 		intlen = asn1_der_length_of(s);
207 		seqlen += 1 + asn1_der_length(intlen) + intlen;
208 
209 		*(data++) = TAG_SEQUENCE;
210 
211 		data += asn1_der_encode_length(data, seqlen);
212 		data += asn1_der_encode(data, r);
213 		data += asn1_der_encode(data, s);
214 
215 		return 1 + asn1_der_length(seqlen) + seqlen;
216 	}
217 
asn1_der_decode_rssig(const byte * data,int size,mpnumber & r,mpnumber & s)218 	int asn1_der_decode_rssig(const byte* data, int size, mpnumber& r, mpnumber& s) throw (asn1error)
219 	{
220 		int tmp, length, offset = 1;
221 
222 		if (size < 2)
223 			throw DER_NOT_ENOUGH_DATA;
224 
225 		if (data[0] != TAG_SEQUENCE)
226 			throw DER_FORMAT_ERROR;
227 
228 		offset += asn1_der_decode_length(data+offset, size-offset, &length);
229 
230 		if (length > (size-offset))
231 			throw DER_NOT_ENOUGH_DATA;
232 
233 		tmp = asn1_der_decode(data+offset, length, r);
234 
235 		offset += tmp;
236 		length -= tmp;
237 
238 		tmp = asn1_der_decode(data+offset, length, s);
239 
240 		offset += tmp;
241 		length -= tmp;
242 
243 		if (length > 0)
244 			throw DER_FORMAT_ERROR;
245 
246 		return offset;
247 	}
248 }
249 
250 using namespace beecrypt::provider;
251 
SHA1withDSASignature()252 SHA1withDSASignature::SHA1withDSASignature()
253 {
254 }
255 
engineGetParameters() const256 AlgorithmParameters* SHA1withDSASignature::engineGetParameters() const
257 {
258 	return 0;
259 }
260 
engineSetParameter(const AlgorithmParameterSpec & spec)261 void SHA1withDSASignature::engineSetParameter(const AlgorithmParameterSpec& spec) throw (InvalidAlgorithmParameterException)
262 {
263 	throw InvalidAlgorithmParameterException("not supported for this algorithm");
264 }
265 
engineInitSign(const PrivateKey & key,SecureRandom * random)266 void SHA1withDSASignature::engineInitSign(const PrivateKey& key, SecureRandom* random) throw (InvalidKeyException)
267 {
268 	const DSAPrivateKey* dsa = dynamic_cast<const DSAPrivateKey*>(&key);
269 	if (dsa)
270 	{
271 		/* copy key information */
272 		transform(_params.p, dsa->getParams().getP());
273 		transform(_params.q, dsa->getParams().getQ());
274 		transform(_params.g, dsa->getParams().getG());
275 		transform(_x, dsa->getX());
276 
277 		/* reset the hash function */
278 		sha1Reset(&_sp);
279 
280 		_srng = random;
281 	}
282 	else
283 		throw InvalidKeyException("key must be a DSAPrivateKey");
284 }
285 
engineInitVerify(const PublicKey & key)286 void SHA1withDSASignature::engineInitVerify(const PublicKey& key) throw (InvalidKeyException)
287 {
288 	const DSAPublicKey* dsa = dynamic_cast<const DSAPublicKey*>(&key);
289 	if (dsa)
290 	{
291 		/* copy key information */
292 		transform(_params.p, dsa->getParams().getP());
293 		transform(_params.q, dsa->getParams().getQ());
294 		transform(_params.g, dsa->getParams().getG());
295 		transform(_y, dsa->getY());
296 
297 		/* reset the hash function */
298 		sha1Reset(&_sp);
299 
300 		_srng = 0;
301 	}
302 	else
303 		throw InvalidKeyException("key must be a DSAPrivateKey");
304 }
305 
engineUpdate(byte b)306 void SHA1withDSASignature::engineUpdate(byte b)
307 {
308 	sha1Update(&_sp, &b, 1);
309 }
310 
engineUpdate(const byte * data,int offset,int len)311 void SHA1withDSASignature::engineUpdate(const byte* data, int offset, int len)
312 {
313 	sha1Update(&_sp, data+offset, len);
314 }
315 
rawsign(mpnumber & r,mpnumber & s)316 void SHA1withDSASignature::rawsign(mpnumber& r, mpnumber& s) throw (SignatureException)
317 {
318 	mpnumber hm;
319 	byte digest[20];
320 
321 	sha1Digest(&_sp, digest);
322 	mpnsetbin(&hm, digest, 20);
323 
324 	if (_srng)
325 	{
326 		randomGeneratorContextAdapter rngc(_srng);
327 		if (dsasign(&_params.p, &_params.q, &_params.g, &rngc, &hm, &_x, &r, &s))
328 			throw SignatureException("internal error in dsasign function");
329 	}
330 	else
331 	{
332 		randomGeneratorContext rngc(randomGeneratorDefault());
333 		if (dsasign(&_params.p, &_params.q, &_params.g, &rngc, &hm, &_x, &r, &s))
334 			throw SignatureException("internal error in dsasign function");
335 	}
336 }
337 
rawvrfy(const mpnumber & r,const mpnumber & s)338 bool SHA1withDSASignature::rawvrfy(const mpnumber& r, const mpnumber& s) throw ()
339 {
340 	mpnumber hm;
341 	byte digest[20];
342 
343 	sha1Digest(&_sp, digest);
344 	mpnsetbin(&hm, digest, 20);
345 
346 	return dsavrfy(&_params.p, &_params.q, &_params.g, &hm, &_y, &r, &s);
347 }
348 
engineSign()349 bytearray* SHA1withDSASignature::engineSign() throw (SignatureException)
350 {
351 	mpnumber r, s;
352 
353 	rawsign(r, s);
354 
355 	bytearray* signature = new bytearray(asn1_der_length_of_rssig(r, s));
356 
357 	asn1_der_encode_rssig(signature->data(), r, s);
358 
359 	return signature;
360 }
361 
engineSign(byte * signature,int offset,int len)362 int SHA1withDSASignature::engineSign(byte* signature, int offset, int len) throw (ShortBufferException, SignatureException)
363 {
364 	if (!signature)
365 		throw NullPointerException();
366 
367 	mpnumber r, s;
368 
369 	rawsign(r, s);
370 
371 	if (asn1_der_length_of_rssig(r, s) > (len - offset))
372 		throw ShortBufferException();
373 
374 	return asn1_der_encode_rssig(signature+offset, r, s);
375 }
376 
engineSign(bytearray & signature)377 int SHA1withDSASignature::engineSign(bytearray& signature) throw (SignatureException)
378 {
379 	mpnumber r, s;
380 
381 	rawsign(r, s);
382 
383 	signature.resize(asn1_der_length_of_rssig(r, s));
384 
385 	return asn1_der_encode_rssig(signature.data(), r, s);
386 }
387 
engineVerify(const byte * signature,int offset,int len)388 bool SHA1withDSASignature::engineVerify(const byte* signature, int offset, int len) throw (SignatureException)
389 {
390 	if (!signature)
391 		throw NullPointerException();
392 
393 	mpnumber r, s;
394 
395 	try
396 	{
397 		asn1_der_decode_rssig(signature+offset, len-offset, r, s);
398 	}
399 	catch (asn1error&)
400 	{
401 		throw SignatureException("invalid signature");
402 	}
403 
404 	return rawvrfy(r, s);
405 }
406