Fixed issue #2219: "add cherry picked from" is not applied when squashing/editing...
[TortoiseGit.git] / src / TortoiseProc / UpdateCrypto.cpp
blobcf910625c950f0293fe22bcd59bd6cd4b621d6ce
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2014 Sven Strickroth <email@cs-ware.de>
4 // Copyright (C) 2014 TortoiseGit
5 // Copyright (C) VLC project (http://videolan.org)
6 // - pgp parsing code was copied from src/misc/update(_crypto)?.c
7 // Copyright (C) The Internet Society (1998). All Rights Reserved.
8 // - crc_octets() was lamely copied from rfc 2440
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software Foundation,
22 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "stdafx.h"
25 #include "UpdateCrypto.h"
26 #include "FormatMessageWrapper.h"
27 #include <atlenc.h>
28 #define NEED_SIGNING_KEY
29 #include "..\version.h"
30 #include "TempFile.h"
32 #define packet_type(c) ((c & 0x3c) >> 2) /* 0x3C = 00111100 */
33 #define packet_header_len(c) ((c & 0x03) + 1) /* number of bytes in a packet header */
35 /* number of data bytes in a MPI */
36 #define mpi_len(mpi) ((scalar_number(mpi, 2) + 7) / 8)
38 #define READ_MPI(n, bits) do { \
39 if (i_read + 2 > i_packet_len) \
40 goto error; \
41 int len = mpi_len(p_buf); \
42 if (len > (bits) / 8 || i_read + 2 + len > i_packet_len) \
43 goto error; \
44 len += 2; \
45 memcpy(n, p_buf, len); \
46 p_buf += len; i_read += len; \
47 } while(0)
49 static inline int scalar_number(const uint8_t *p, int header_len)
51 ASSERT(header_len == 1 || header_len == 2 || header_len == 4);
53 if (header_len == 1)
54 return p[0];
55 else if (header_len == 2)
56 return (p[0] << 8) + p[1];
57 else if (header_len == 4)
58 return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
59 else
60 abort();
63 /* Base64 decoding */
64 static size_t b64_decode_binary_to_buffer(uint8_t *p_dst, size_t i_dst, const char *p_src, size_t srcLen)
66 int len = (int)i_dst;
67 if (!Base64Decode(p_src, (int)srcLen, p_dst, &len))
68 return 0;
69 return len;
73 * crc_octets() was lamely copied from rfc 2440
74 * Copyright (C) The Internet Society (1998). All Rights Reserved.
76 #define CRC24_INIT 0xB704CEL
77 #define CRC24_POLY 0x1864CFBL
79 static long crc_octets(uint8_t *octets, size_t len)
81 long crc = CRC24_INIT;
82 int i;
83 while (len--)
85 crc ^= (*octets++) << 16;
86 for (i = 0; i < 8; i++)
88 crc <<= 1;
89 if (crc & 0x1000000)
90 crc ^= CRC24_POLY;
93 return crc & 0xFFFFFFL;
96 static size_t parse_signature_v3_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
98 size_t i_read = 1; /* we already read the version byte */
100 if (i_sig_len < 19) /* signature is at least 19 bytes + the 2 MPIs */
101 return 0;
103 p_sig->specific.v3.hashed_data_len = *p_buf++; i_read++;
104 if (p_sig->specific.v3.hashed_data_len != 5)
105 return 0;
107 p_sig->type = *p_buf++; i_read++;
109 memcpy(p_sig->specific.v3.timestamp, p_buf, 4);
110 p_buf += 4; i_read += 4;
112 memcpy(p_sig->issuer_longid, p_buf, 8);
113 p_buf += 8; i_read += 8;
115 p_sig->public_key_algo = *p_buf++; i_read++;
117 p_sig->digest_algo = *p_buf++; i_read++;
119 p_sig->hash_verification[0] = *p_buf++; i_read++;
120 p_sig->hash_verification[1] = *p_buf++; i_read++;
122 ASSERT(i_read == 19);
124 return i_read;
128 * fill a signature_packet_v4_t from signature packet data
129 * verify that it was used with a DSA public key, using SHA-1 digest
131 static size_t parse_signature_v4_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
133 size_t i_read = 1; /* we already read the version byte */
135 if (i_sig_len < 10) /* signature is at least 10 bytes + the 2 MPIs */
136 return 0;
138 p_sig->type = *p_buf++; i_read++;
140 p_sig->public_key_algo = *p_buf++; i_read++;
142 p_sig->digest_algo = *p_buf++; i_read++;
144 memcpy(p_sig->specific.v4.hashed_data_len, p_buf, 2);
145 p_buf += 2; i_read += 2;
147 size_t i_hashed_data_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
148 i_read += i_hashed_data_len;
149 if (i_read + 4 > i_sig_len)
150 return 0;
152 p_sig->specific.v4.hashed_data = (uint8_t*) malloc(i_hashed_data_len);
153 if (!p_sig->specific.v4.hashed_data)
154 return 0;
155 memcpy(p_sig->specific.v4.hashed_data, p_buf, i_hashed_data_len);
156 p_buf += i_hashed_data_len;
158 memcpy(p_sig->specific.v4.unhashed_data_len, p_buf, 2);
159 p_buf += 2; i_read += 2;
161 size_t i_unhashed_data_len = scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
162 i_read += i_unhashed_data_len;
163 if (i_read + 2 > i_sig_len)
164 return 0;
166 p_sig->specific.v4.unhashed_data = (uint8_t*) malloc(i_unhashed_data_len);
167 if (!p_sig->specific.v4.unhashed_data)
168 return 0;
170 memcpy(p_sig->specific.v4.unhashed_data, p_buf, i_unhashed_data_len);
171 p_buf += i_unhashed_data_len;
173 memcpy(p_sig->hash_verification, p_buf, 2);
174 p_buf += 2; i_read += 2;
176 uint8_t *p, *max_pos;
177 p = p_sig->specific.v4.unhashed_data;
178 max_pos = p + scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
180 for (;;)
182 if (p > max_pos)
183 return 0;
185 size_t i_subpacket_len;
186 if (*p < 192)
188 if (p + 1 > max_pos)
189 return 0;
190 i_subpacket_len = *p++;
192 else if (*p < 255)
194 if (p + 2 > max_pos)
195 return 0;
196 i_subpacket_len = (*p++ - 192) << 8;
197 i_subpacket_len += *p++ + 192;
199 else
201 if (p + 4 > max_pos)
202 return 0;
203 i_subpacket_len = *++p << 24;
204 i_subpacket_len += *++p << 16;
205 i_subpacket_len += *++p << 8;
206 i_subpacket_len += *++p;
209 if (*p == ISSUER_SUBPACKET)
211 if (p + 9 > max_pos)
212 return 0;
214 memcpy(&p_sig->issuer_longid, p + 1, 8);
216 return i_read;
219 p += i_subpacket_len;
223 static int parse_signature_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_packet_len)
225 if (!i_packet_len) /* 1st sanity check, we need at least the version */
226 return -1;
228 p_sig->version = *p_buf++;
230 size_t i_read;
231 switch (p_sig->version)
233 case 3:
234 i_read = parse_signature_v3_packet(p_sig, p_buf, i_packet_len);
235 break;
236 case 4:
237 p_sig->specific.v4.hashed_data = nullptr;
238 p_sig->specific.v4.unhashed_data = nullptr;
239 i_read = parse_signature_v4_packet(p_sig, p_buf, i_packet_len);
240 break;
241 default:
242 return -1;
245 if (i_read == 0) /* signature packet parsing has failed */
246 goto error;
248 if (p_sig->public_key_algo != PUBLIC_KEY_ALGO_DSA)
249 goto error;
251 if (p_sig->digest_algo != DIGEST_ALGO_SHA1)
252 goto error;
254 switch (p_sig->type)
256 case BINARY_SIGNATURE:
257 case TEXT_SIGNATURE:
258 case GENERIC_KEY_SIGNATURE:
259 case PERSONA_KEY_SIGNATURE:
260 case CASUAL_KEY_SIGNATURE:
261 case POSITIVE_KEY_SIGNATURE:
262 break;
263 default:
264 goto error;
267 p_buf--; /* rewind to the version byte */
268 p_buf += i_read;
270 READ_MPI(p_sig->r, 160);
271 READ_MPI(p_sig->s, 160);
273 ASSERT(i_read == i_packet_len);
274 if (i_read < i_packet_len) /* some extra data, hm ? */
275 goto error;
277 return 0;
279 error:
280 if (p_sig->version == 4)
282 free(p_sig->specific.v4.hashed_data);
283 free(p_sig->specific.v4.unhashed_data);
286 return -1;
290 * Transform an armored document in binary format
291 * Used on public keys and signatures
293 static int pgp_unarmor(const char *p_ibuf, size_t i_ibuf_len, uint8_t *p_obuf, size_t i_obuf_len)
295 const char *p_ipos = p_ibuf;
296 uint8_t *p_opos = p_obuf;
297 int i_end = 0;
298 int i_header_skipped = 0;
300 while (!i_end && p_ipos < p_ibuf + i_ibuf_len && *p_ipos != '=')
302 if (*p_ipos == '\r' || *p_ipos == '\n')
304 p_ipos++;
305 continue;
308 size_t i_line_len = strcspn(p_ipos, "\r\n");
309 if (i_line_len == 0)
310 continue;
312 if (!i_header_skipped)
314 if (!strncmp(p_ipos, "-----BEGIN PGP", 14))
315 i_header_skipped = 1;
317 p_ipos += i_line_len + 1;
318 continue;
321 if (!strncmp(p_ipos, "Version:", 8))
323 p_ipos += i_line_len + 1;
324 continue;
327 if (p_ipos[i_line_len - 1] == '=')
329 i_end = 1;
332 p_opos += b64_decode_binary_to_buffer(p_opos, p_obuf - p_opos + i_obuf_len, p_ipos, (int)i_line_len);
333 p_ipos += i_line_len + 1;
336 if (p_ipos + 1 < p_ibuf + i_ibuf_len && (*p_ipos == '\r' || *p_ipos == '\n'))
337 p_ipos++;
339 /* XXX: the CRC is OPTIONAL, really require it ? */
340 if (p_ipos + 5 > p_ibuf + i_ibuf_len || *p_ipos++ != '=')
341 return 0;
343 uint8_t p_crc[3];
344 if (b64_decode_binary_to_buffer(p_crc, sizeof(p_crc), p_ipos, 5) != 3)
345 return 0;
347 long l_crc = crc_octets(p_obuf, p_opos - p_obuf);
348 long l_crc2 = (0 << 24) + (p_crc[0] << 16) + (p_crc[1] << 8) + p_crc[2];
350 return (int)((l_crc2 == l_crc) ? p_opos - p_obuf : 0);
354 * fill a public_key_packet_t structure from public key packet data
355 * verify that it is a version 4 public key packet, using DSA
357 static int parse_public_key_packet(public_key_packet_t *p_key, const uint8_t *p_buf, size_t i_packet_len)
359 if (i_packet_len > 418 || i_packet_len < 6)
360 return -1;
362 size_t i_read = 0;
364 p_key->version = *p_buf++; i_read++;
365 if (p_key->version != 4)
366 return -1;
368 /* XXX: warn when timestamp is > date ? */
369 memcpy(p_key->timestamp, p_buf, 4); p_buf += 4; i_read += 4;
371 p_key->algo = *p_buf++; i_read++;
372 if (p_key->algo != PUBLIC_KEY_ALGO_DSA)
373 return -1;
375 READ_MPI(p_key->p, 1024);
376 READ_MPI(p_key->q, 160);
377 READ_MPI(p_key->g, 1024);
378 READ_MPI(p_key->y, 1024);
380 if (i_read != i_packet_len) /* some extra data eh ? */
381 return -1;
383 return 0;
385 error:
386 return -1;
390 * fill a public_key_t with public key data, including:
391 * * public key packet
392 * * signature packet issued by key which long id is p_sig_issuer
393 * * user id packet
395 static int parse_public_key(const uint8_t *p_key_data, size_t i_key_len, public_key_t *p_key, const uint8_t *p_sig_issuer)
397 const uint8_t *pos = p_key_data;
398 const uint8_t *max_pos = pos + i_key_len;
400 int i_status = 0;
401 #define PUBLIC_KEY_FOUND 0x01
402 #define USER_ID_FOUND 0x02
403 #define SIGNATURE_FOUND 0X04
405 uint8_t *p_key_unarmored = nullptr;
407 p_key->psz_username = nullptr;
408 p_key->sig.specific.v4.hashed_data = nullptr;
409 p_key->sig.specific.v4.unhashed_data = nullptr;
411 if (!(*pos & 0x80))
412 { /* first byte is ASCII, unarmoring */
413 p_key_unarmored = (uint8_t*)malloc(i_key_len);
414 if (!p_key_unarmored)
415 return -1;
416 int i_len = pgp_unarmor((char*)p_key_data, i_key_len, p_key_unarmored, i_key_len);
418 if (i_len == 0)
419 goto error;
421 pos = p_key_unarmored;
422 max_pos = pos + i_len;
425 while (pos < max_pos)
427 if (!(*pos & 0x80) || *pos & 0x40)
428 goto error;
430 int i_type = packet_type(*pos);
432 int i_header_len = packet_header_len(*pos++);
433 if (pos + i_header_len > max_pos || (i_header_len != 1 && i_header_len != 2 && i_header_len != 4))
434 goto error;
436 int i_packet_len = scalar_number(pos, i_header_len);
437 pos += i_header_len;
439 if (pos + i_packet_len > max_pos)
440 goto error;
442 switch (i_type)
444 case PUBLIC_KEY_PACKET:
445 i_status |= PUBLIC_KEY_FOUND;
446 if (parse_public_key_packet(&p_key->key, pos, i_packet_len) != 0)
447 goto error;
448 break;
450 case SIGNATURE_PACKET: /* we accept only v4 signatures here */
451 if (i_status & SIGNATURE_FOUND || !p_sig_issuer)
452 break;
453 if (parse_signature_packet(&p_key->sig, pos, i_packet_len) == 0)
455 if (p_key->sig.version != 4)
456 break;
457 if (memcmp( p_key->sig.issuer_longid, p_sig_issuer, 8))
459 free(p_key->sig.specific.v4.hashed_data);
460 free(p_key->sig.specific.v4.unhashed_data);
461 p_key->sig.specific.v4.hashed_data = nullptr;
462 p_key->sig.specific.v4.unhashed_data = nullptr;
463 break;
465 i_status |= SIGNATURE_FOUND;
467 break;
469 case USER_ID_PACKET:
470 if (p_key->psz_username) /* save only the first User ID */
471 break;
472 i_status |= USER_ID_FOUND;
473 p_key->psz_username = (uint8_t*)malloc(i_packet_len + 1);
474 if (!p_key->psz_username)
475 goto error;
477 memcpy(p_key->psz_username, pos, i_packet_len);
478 p_key->psz_username[i_packet_len] = '\0';
479 break;
481 default:
482 break;
484 pos += i_packet_len;
486 free(p_key_unarmored);
488 if (!(i_status & (PUBLIC_KEY_FOUND | USER_ID_FOUND)))
489 return -1;
491 if (p_sig_issuer && !(i_status & SIGNATURE_FOUND))
492 return -1;
494 return 0;
496 error:
497 if (p_key->sig.version == 4)
499 free(p_key->sig.specific.v4.hashed_data);
500 free(p_key->sig.specific.v4.unhashed_data);
502 free(p_key->psz_username);
503 free(p_key_unarmored);
504 return -1;
507 static int LoadSignature(const CString &signatureFilename, signature_packet_t *p_sig)
509 FILE * pFile = _tfsopen(signatureFilename, _T("rb"), SH_DENYWR);
510 if (pFile)
512 int size = 65536;
513 std::unique_ptr<unsigned char[]> buffer(new unsigned char[size]);
514 int length = 0;
515 if ((length = (int)fread(buffer.get(), sizeof(char), size, pFile)) >= 8)
517 fclose(pFile);
518 // is unpacking needed?
519 if ((uint8_t)buffer[0] < 0x80)
521 std::unique_ptr<unsigned char[]> unpacked(new unsigned char[size]);
522 size = pgp_unarmor((char *)buffer.get(), length, unpacked.get(), length);
524 if (size < 2)
525 return -1;
527 buffer.swap(unpacked);
529 else
530 size = length;
532 if (packet_type(buffer[0]) != SIGNATURE_PACKET)
533 return -1;
535 DWORD i_header_len = packet_header_len(buffer[0]);
536 if ((i_header_len != 1 && i_header_len != 2 && i_header_len != 4) || i_header_len + 1 > (DWORD)size)
537 return -1;
539 DWORD i_len = scalar_number((uint8_t *)(buffer.get() + 1), i_header_len);
540 if (i_len + i_header_len + 1 != (DWORD)size)
541 return -1;
543 if (parse_signature_packet(p_sig, (uint8_t *)(buffer.get() + 1 + i_header_len), i_len))
544 return -1;
546 if (p_sig->type != BINARY_SIGNATURE && p_sig->type != TEXT_SIGNATURE)
548 if (p_sig->version == 4)
550 free(p_sig->specific.v4.hashed_data);
551 free(p_sig->specific.v4.unhashed_data);
553 return -1;
556 return 0;
558 else
559 fclose(pFile);
561 return -1;
564 static void CryptHashChar(HCRYPTHASH hHash, const int c)
566 CryptHashData(hHash, (BYTE *)&c, 1, 0);
569 /* final part of the hash */
570 static int hash_finish(HCRYPTHASH hHash, signature_packet_t *p_sig)
572 if (p_sig->version == 3)
574 CryptHashChar(hHash, p_sig->type);
575 CryptHashData(hHash, (unsigned char*)&p_sig->specific.v3.timestamp, 4, 0);
577 else if (p_sig->version == 4)
579 CryptHashChar(hHash, p_sig->version);
580 CryptHashChar(hHash, p_sig->type);
581 CryptHashChar(hHash, p_sig->public_key_algo);
582 CryptHashChar(hHash, p_sig->digest_algo);
583 CryptHashData(hHash, p_sig->specific.v4.hashed_data_len, 2, 0);
584 unsigned int i_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
585 CryptHashData(hHash, p_sig->specific.v4.hashed_data, i_len, 0);
587 CryptHashChar(hHash, 0x04);
588 CryptHashChar(hHash, 0xFF);
590 i_len += 6; /* hashed data + 6 bytes header */
592 CryptHashChar(hHash, (i_len >> 24) & 0xff);
593 CryptHashChar(hHash, (i_len >> 16) & 0xff);
594 CryptHashChar(hHash, (i_len >> 8) & 0xff);
595 CryptHashChar(hHash, (i_len) & 0xff);
597 else
598 { /* RFC 4880 only tells about versions 3 and 4 */
599 return -1;
602 return 0;
606 * Generate a SHA1 hash on a public key, to verify a signature made on that hash
607 * Note that we need the signature (v4) to compute the hash
609 static int hash_sha1_from_public_key(HCRYPTHASH hHash, public_key_t *p_pkey)
611 if (p_pkey->sig.version != 4)
612 return -1;
614 if (p_pkey->sig.type < GENERIC_KEY_SIGNATURE || p_pkey->sig.type > POSITIVE_KEY_SIGNATURE)
615 return -1;
617 CryptHashChar(hHash, 0x99);
619 unsigned int i_p_len = mpi_len(p_pkey->key.p);
620 unsigned int i_g_len = mpi_len(p_pkey->key.g);
621 unsigned int i_q_len = mpi_len(p_pkey->key.q);
622 unsigned int i_y_len = mpi_len(p_pkey->key.y);
624 DWORD i_size = 6 + 2*4 + i_p_len + i_g_len + i_q_len + i_y_len;
626 CryptHashChar(hHash, (i_size >> 8) & 0xff);
627 CryptHashChar(hHash, i_size & 0xff);
629 CryptHashChar(hHash, p_pkey->key.version);
630 CryptHashData(hHash, p_pkey->key.timestamp, 4, 0);
631 CryptHashChar(hHash, p_pkey->key.algo);
633 CryptHashData(hHash, (uint8_t*)&p_pkey->key.p, 2, 0);
634 CryptHashData(hHash, (uint8_t*)&p_pkey->key.p + 2, i_p_len, 0);
636 CryptHashData(hHash, (uint8_t*)&p_pkey->key.q, 2, 0);
637 CryptHashData(hHash, (uint8_t*)&p_pkey->key.q + 2, i_q_len, 0);
639 CryptHashData(hHash, (uint8_t*)&p_pkey->key.g, 2, 0);
640 CryptHashData(hHash, (uint8_t*)&p_pkey->key.g + 2, i_g_len, 0);
642 CryptHashData(hHash, (uint8_t*)&p_pkey->key.y, 2, 0);
643 CryptHashData(hHash, (uint8_t*)&p_pkey->key.y + 2, i_y_len, 0);
645 CryptHashChar(hHash, 0xb4);
647 size_t i_len = strlen((char *)p_pkey->psz_username);
649 CryptHashChar(hHash, (i_len >> 24) & 0xff);
650 CryptHashChar(hHash, (i_len >> 16) & 0xff);
651 CryptHashChar(hHash, (i_len >> 8) & 0xff);
652 CryptHashChar(hHash, (i_len) & 0xff);
654 CryptHashData(hHash, p_pkey->psz_username, (DWORD)i_len, 0);
656 return hash_finish(hHash, &p_pkey->sig);
659 static int hash_sha1_from_file(HCRYPTHASH hHash, CString filename, signature_packet_t *p_sig)
661 FILE * pFile = _tfsopen(filename, _T("rb"), SH_DENYWR);
662 if (!pFile)
663 return -1;
665 char buf[4097] = { 0 };
666 int read = 0;
667 int nlHandling = 0;
668 while ((read = (int)fread(buf, sizeof(char), sizeof(buf) - 1, pFile)) > 0)
670 if (p_sig->type == TEXT_SIGNATURE)
672 buf[read] = 0;
673 char * psz_string = buf;
674 while (*psz_string)
676 if (nlHandling == 1 && (*psz_string == '\r' || *psz_string == '\n'))
678 CryptHashChar(hHash, '\r');
679 CryptHashChar(hHash, '\n');
680 nlHandling = 2;
682 if (nlHandling == 2 && *psz_string == '\r')
684 psz_string++;
685 nlHandling = 2;
686 if (!*psz_string)
687 break;
690 if ((nlHandling == 2 || nlHandling == 3) && *psz_string == '\n')
692 psz_string++;
693 if (!*psz_string)
694 break;
697 size_t i_len = strcspn(psz_string, "\r\n");
699 if (i_len)
701 CryptHashData(hHash, (BYTE *)psz_string, (DWORD)i_len, 0);
702 psz_string += i_len;
705 nlHandling = 1;
706 if (*psz_string == '\r' || *psz_string == '\n')
708 CryptHashChar(hHash, '\r');
709 CryptHashChar(hHash, '\n');
710 nlHandling = 2;
712 if (*psz_string == '\r')
714 psz_string++;
715 nlHandling = 3;
718 if (*psz_string == '\n')
720 psz_string++;
721 nlHandling = 0;
726 else
727 CryptHashData(hHash, (BYTE *)buf, read, 0);
730 fclose(pFile);
732 return hash_finish(hHash, p_sig);
735 static int check_hash(HCRYPTHASH hHash, signature_packet_t *p_sig)
737 DWORD len = 20;
738 unsigned char hash[20] = { 0 };
739 CryptGetHashParam(hHash, HP_HASHVAL, hash, &len, 0);
741 if (hash[0] != p_sig->hash_verification[0] || hash[1] != p_sig->hash_verification[1])
742 return -1;
744 return 0;
747 static int verify_signature(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t &p_pkey, signature_packet_t &p_sig)
749 HCRYPTKEY hPubKey;
750 // based on http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-10/0040.html
751 DSAKEY dsakey;
752 dsakey.blobheader.bType = PUBLICKEYBLOB; // 0x06
753 dsakey.blobheader.bVersion = CUR_BLOB_VERSION + 1; // 0x03
754 dsakey.blobheader.reserved = 0;
755 dsakey.blobheader.aiKeyAlg = CALG_DSS_SIGN;
756 dsakey.dsspubkeyver3.magic = 0x33535344; // ASCII of "DSS3";
757 dsakey.dsspubkeyver3.bitlenP = 1024; // # of bits in prime modulus
758 dsakey.dsspubkeyver3.bitlenQ = 160; // # of bits in prime q, 0 if not available
759 dsakey.dsspubkeyver3.bitlenJ = 0; // # of bits in (p-1)/q, 0 if not available
760 dsakey.dsspubkeyver3.DSSSeed.counter = 0xFFFFFFFF; // not available
762 memcpy(dsakey.p, p_pkey.key.p + 2, sizeof(p_pkey.key.p) - 2); std::reverse(dsakey.p, dsakey.p + sizeof(dsakey.p));
763 memcpy(dsakey.q, p_pkey.key.q + 2, sizeof(p_pkey.key.q) - 2); std::reverse(dsakey.q, dsakey.q + sizeof(dsakey.q));
764 memcpy(dsakey.g, p_pkey.key.g + 2, sizeof(p_pkey.key.g) - 2); std::reverse(dsakey.g, dsakey.g + sizeof(dsakey.g));
765 memcpy(dsakey.y, p_pkey.key.y + 2, sizeof(p_pkey.key.y) - 2); std::reverse(dsakey.y, dsakey.y + sizeof(dsakey.y));
767 if (CryptImportKey(hCryptProv, (BYTE*)&dsakey, sizeof(dsakey), 0, 0, &hPubKey) == 0)
768 return -1;
770 unsigned char signature[40] = { 0 };
771 memcpy(signature, p_sig.r + 2, 20);
772 memcpy(signature + 20, p_sig.s + 2, 20);
773 std::reverse(signature, signature + 20);
774 std::reverse(signature + 20, signature + 40);
775 if (!CryptVerifySignature(hHash, signature, sizeof(signature), hPubKey, nullptr, 0))
777 CryptDestroyKey(hPubKey);
778 return -1;
781 CryptDestroyKey(hPubKey);
782 return 0;
786 * download a public key (the last one) from TortoiseGit server, and parse it
788 static public_key_t *download_key(const uint8_t *p_longid, const uint8_t *p_signature_issuer, CUpdateDownloader *updateDownloader)
790 ASSERT(updateDownloader);
792 CString url;
793 url.Format(L"http://download.tortoisegit.org/keys/%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X.asc", p_longid[0], p_longid[1], p_longid[2], p_longid[3], p_longid[4], p_longid[5], p_longid[6], p_longid[7]);
795 CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
796 if (updateDownloader->DownloadFile(url, tempfile, false))
797 return nullptr;
799 int size = 65536;
800 std::unique_ptr<char[]> buffer(new char[size]);
801 FILE * pFile = _tfsopen(tempfile, _T("rb"), SH_DENYWR);
802 if (pFile)
804 int length = 0;
805 if ((length = (int)fread(buffer.get(), sizeof(char), size, pFile)) >= 8)
807 fclose(pFile);
808 size = length;
810 else
812 fclose(pFile);
813 return nullptr;
816 else
817 return nullptr;
819 public_key_t *p_pkey = (public_key_t*) malloc(sizeof(public_key_t));
820 if (!p_pkey)
822 DeleteUrlCacheEntry(url);
823 return nullptr;
826 memcpy(p_pkey->longid, p_longid, 8);
828 if (parse_public_key((const uint8_t *)buffer.get(), size, p_pkey, p_signature_issuer))
830 free(p_pkey);
831 return nullptr;
834 return p_pkey;
837 int VerifyIntegrity(const CString &filename, const CString &signatureFilename, CUpdateDownloader *updateDownloader)
839 ASSERT(updateDownloader);
841 signature_packet_t p_sig;
842 memset(&p_sig, 0, sizeof(signature_packet_t));
843 if (LoadSignature(signatureFilename, &p_sig))
844 return -1;
846 public_key_t p_pkey;
847 memset(&p_pkey, 0, sizeof(public_key_t));
848 if (parse_public_key(tortoisegit_public_key, sizeof(tortoisegit_public_key), &p_pkey, nullptr))
850 if (p_sig.version == 4)
852 free(p_sig.specific.v4.hashed_data);
853 free(p_sig.specific.v4.unhashed_data);
855 return -1;
857 memcpy(p_pkey.longid, tortoisegit_public_key_longid, 8);
859 HCRYPTPROV hCryptProv;
860 if (!CryptAcquireContext(&hCryptProv, nullptr, nullptr, PROV_DSS, CRYPT_VERIFYCONTEXT))
862 if (p_sig.version == 4)
864 free(p_sig.specific.v4.hashed_data);
865 free(p_sig.specific.v4.unhashed_data);
867 free(p_pkey.psz_username);
868 return -1;
871 if (memcmp(p_sig.issuer_longid, p_pkey.longid, 8) != 0)
873 public_key_t *p_new_pkey = download_key(p_sig.issuer_longid, tortoisegit_public_key_longid, updateDownloader);
874 if (!p_new_pkey)
876 if (p_sig.version == 4)
878 free(p_sig.specific.v4.hashed_data);
879 free(p_sig.specific.v4.unhashed_data);
881 free(p_pkey.psz_username);
882 CryptReleaseContext(hCryptProv, 0);
883 return -1;
886 HCRYPTHASH hHash;
887 if (!CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash))
889 if (p_sig.version == 4)
891 free(p_sig.specific.v4.hashed_data);
892 free(p_sig.specific.v4.unhashed_data);
894 free(p_pkey.psz_username);
895 CryptReleaseContext(hCryptProv, 0);
896 free(p_new_pkey->psz_username);
897 if (p_new_pkey->sig.version == 4)
899 free(p_new_pkey->sig.specific.v4.hashed_data);
900 free(p_new_pkey->sig.specific.v4.unhashed_data);
902 free(p_new_pkey);
903 return -1;
906 if (hash_sha1_from_public_key(hHash, p_new_pkey))
908 if (p_sig.version == 4)
910 free(p_sig.specific.v4.hashed_data);
911 free(p_sig.specific.v4.unhashed_data);
913 free(p_pkey.psz_username);
914 CryptReleaseContext(hCryptProv, 0);
915 free(p_new_pkey->psz_username);
916 if (p_new_pkey->sig.version == 4)
918 free(p_new_pkey->sig.specific.v4.hashed_data);
919 free(p_new_pkey->sig.specific.v4.unhashed_data);
921 free(p_new_pkey);
922 CryptDestroyHash(hHash);
923 return -1;
926 if (check_hash(hHash, &p_new_pkey->sig))
928 if (p_sig.version == 4)
930 free(p_sig.specific.v4.hashed_data);
931 free(p_sig.specific.v4.unhashed_data);
933 free(p_pkey.psz_username);
934 CryptReleaseContext(hCryptProv, 0);
935 free(p_new_pkey->psz_username);
936 if (p_new_pkey->sig.version == 4)
938 free(p_new_pkey->sig.specific.v4.hashed_data);
939 free(p_new_pkey->sig.specific.v4.unhashed_data);
941 free(p_new_pkey);
942 CryptDestroyHash(hHash);
943 return -1;
946 if (verify_signature(hCryptProv, hHash, p_pkey, p_new_pkey->sig))
948 if (p_sig.version == 4)
950 free(p_sig.specific.v4.hashed_data);
951 free(p_sig.specific.v4.unhashed_data);
953 free(p_pkey.psz_username);
954 CryptReleaseContext(hCryptProv, 0);
955 free(p_new_pkey->psz_username);
956 if (p_new_pkey->sig.version == 4)
958 free(p_new_pkey->sig.specific.v4.hashed_data);
959 free(p_new_pkey->sig.specific.v4.unhashed_data);
961 free(p_new_pkey);
962 CryptDestroyHash(hHash);
963 return -1;
965 else
967 CryptDestroyHash(hHash);
968 free(p_pkey.psz_username);
969 p_pkey = *p_new_pkey;
970 if (p_pkey.sig.version == 4)
972 p_pkey.sig.version = 0;
973 free(p_pkey.sig.specific.v4.hashed_data);
974 free(p_pkey.sig.specific.v4.unhashed_data);
976 free(p_new_pkey);
980 int nRetCode = -1;
982 HCRYPTHASH hHash;
983 if (!CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash))
984 goto error;
986 if (hash_sha1_from_file(hHash, filename, &p_sig))
987 goto error;
989 if (check_hash(hHash, &p_sig))
990 goto error;
992 if (verify_signature(hCryptProv, hHash, p_pkey, p_sig))
993 goto error;
995 nRetCode = 0;
997 error:
998 CryptDestroyHash(hHash);
999 CryptReleaseContext(hCryptProv, 0);
1001 free(p_pkey.psz_username);
1002 if (p_sig.version == 4)
1004 free(p_sig.specific.v4.hashed_data);
1005 free(p_sig.specific.v4.unhashed_data);
1008 return nRetCode;