Fixed issue #2495: "Show Reflog" dialog shows empty action for "push" entries
[TortoiseGit.git] / src / TortoiseProc / UpdateCrypto.cpp
blob57f84f6f578680cb2926242aee007e1b5bbb6e59
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2015 Sven Strickroth <email@cs-ware.de>
4 // Copyright (C) 2014-2015 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 static inline int scalar_number(const uint8_t *p, int header_len)
37 ASSERT(header_len == 1 || header_len == 2 || header_len == 4);
39 if (header_len == 1)
40 return p[0];
41 else if (header_len == 2)
42 return (p[0] << 8) + p[1];
43 else if (header_len == 4)
44 return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
45 else
46 abort();
49 /* number of data bytes in a MPI */
50 static int mpi_len(const uint8_t* mpi)
52 return (scalar_number(mpi, 2) + 7) / 8;
55 static size_t read_mpi(uint8_t* dst, const uint8_t* buf, size_t buflen, size_t bits)
57 if (buflen < 2)
58 return 0;
60 size_t n = mpi_len(buf);
62 if (n * 8 > bits)
63 return 0;
65 n += 2;
67 if (buflen < n)
68 return 0;
70 memcpy(dst, buf, n);
71 return n;
74 #define READ_MPI(d, bits) do \
75 { \
76 size_t n = read_mpi(d, p_buf, i_packet_len - i_read, bits); \
77 if (!n) goto error; \
78 p_buf += n; \
79 i_read += n; \
80 } while(0)
82 /* Base64 decoding */
83 static size_t b64_decode_binary_to_buffer(uint8_t *p_dst, size_t i_dst, const char *p_src, size_t srcLen)
85 int len = (int)i_dst;
86 if (!Base64Decode(p_src, (int)srcLen, p_dst, &len))
87 return 0;
88 return len;
92 * crc_octets() was lamely copied from rfc 2440
93 * Copyright (C) The Internet Society (1998). All Rights Reserved.
95 #define CRC24_INIT 0xB704CEL
96 #define CRC24_POLY 0x1864CFBL
98 static long crc_octets(uint8_t *octets, size_t len)
100 long crc = CRC24_INIT;
101 int i;
102 while (len--)
104 crc ^= (*octets++) << 16;
105 for (i = 0; i < 8; i++)
107 crc <<= 1;
108 if (crc & 0x1000000)
109 crc ^= CRC24_POLY;
112 return crc & 0xFFFFFFL;
115 static ALG_ID map_digestalgo(uint8_t digest_algo)
117 switch (digest_algo)
119 case DIGEST_ALGO_SHA1:
120 return CALG_SHA1;
121 case DIGEST_ALGO_SHA256:
122 return CALG_SHA_256;
123 case DIGEST_ALGO_SHA384:
124 return CALG_SHA_384;
125 case DIGEST_ALGO_SHA512:
126 return CALG_SHA_512;
127 default:
128 return 0;
132 static DWORD map_algo(uint8_t digest_algo)
134 switch (digest_algo)
136 case PUBLIC_KEY_ALGO_DSA:
137 return PROV_DSS;
138 case PUBLIC_KEY_ALGO_RSA:
139 return PROV_RSA_AES; // needed for SHA2, see http://msdn.microsoft.com/en-us/library/windows/desktop/aa387447%28v=vs.85%29.aspx
140 default:
141 return 0;
145 static size_t parse_signature_v3_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
147 size_t i_read = 1; /* we already read the version byte */
149 if (i_sig_len < 19) /* signature is at least 19 bytes + the 2 MPIs */
150 return 0;
152 p_sig->specific.v3.hashed_data_len = *p_buf++; i_read++;
153 if (p_sig->specific.v3.hashed_data_len != 5)
154 return 0;
156 p_sig->type = *p_buf++; i_read++;
158 memcpy(p_sig->specific.v3.timestamp, p_buf, 4);
159 p_buf += 4; i_read += 4;
161 memcpy(p_sig->issuer_longid, p_buf, 8);
162 p_buf += 8; i_read += 8;
164 p_sig->public_key_algo = *p_buf++; i_read++;
166 p_sig->digest_algo = *p_buf++; i_read++;
168 p_sig->hash_verification[0] = *p_buf++; i_read++;
169 p_sig->hash_verification[1] = *p_buf++; i_read++;
171 ASSERT(i_read == 19);
173 return i_read;
177 * fill a signature_packet_v4_t from signature packet data
178 * verify that it was used with a DSA or RSA public key
180 static size_t parse_signature_v4_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
182 size_t i_read = 1; /* we already read the version byte */
184 if (i_sig_len < 10) /* signature is at least 10 bytes + the 2 MPIs */
185 return 0;
187 p_sig->type = *p_buf++; i_read++;
189 p_sig->public_key_algo = *p_buf++; i_read++;
191 p_sig->digest_algo = *p_buf++; i_read++;
192 if (!map_algo(p_sig->public_key_algo))
193 return 0;
195 memcpy(p_sig->specific.v4.hashed_data_len, p_buf, 2);
196 p_buf += 2; i_read += 2;
198 size_t i_hashed_data_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
199 i_read += i_hashed_data_len;
200 if (i_read + 4 > i_sig_len)
201 return 0;
203 p_sig->specific.v4.hashed_data = (uint8_t*) malloc(i_hashed_data_len);
204 if (!p_sig->specific.v4.hashed_data)
205 return 0;
206 memcpy(p_sig->specific.v4.hashed_data, p_buf, i_hashed_data_len);
207 p_buf += i_hashed_data_len;
209 memcpy(p_sig->specific.v4.unhashed_data_len, p_buf, 2);
210 p_buf += 2; i_read += 2;
212 size_t i_unhashed_data_len = scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
213 i_read += i_unhashed_data_len;
214 if (i_read + 2 > i_sig_len)
215 return 0;
217 p_sig->specific.v4.unhashed_data = (uint8_t*) malloc(i_unhashed_data_len);
218 if (!p_sig->specific.v4.unhashed_data)
219 return 0;
221 memcpy(p_sig->specific.v4.unhashed_data, p_buf, i_unhashed_data_len);
222 p_buf += i_unhashed_data_len;
224 memcpy(p_sig->hash_verification, p_buf, 2);
225 p_buf += 2; i_read += 2;
227 uint8_t *p, *max_pos;
228 p = p_sig->specific.v4.unhashed_data;
229 max_pos = p + scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
231 for (;;)
233 if (p > max_pos)
234 return 0;
236 size_t i_subpacket_len;
237 if (*p < 192)
239 if (p + 1 > max_pos)
240 return 0;
241 i_subpacket_len = *p++;
243 else if (*p < 255)
245 if (p + 2 > max_pos)
246 return 0;
247 i_subpacket_len = (*p++ - 192) << 8;
248 i_subpacket_len += *p++ + 192;
250 else
252 if (p + 4 > max_pos)
253 return 0;
254 i_subpacket_len = size_t(*++p) << 24;
255 i_subpacket_len += *++p << 16;
256 i_subpacket_len += *++p << 8;
257 i_subpacket_len += *++p;
260 if (*p == ISSUER_SUBPACKET)
262 if (p + 9 > max_pos)
263 return 0;
265 memcpy(&p_sig->issuer_longid, p + 1, 8);
267 return i_read;
270 p += i_subpacket_len;
274 static int parse_signature_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_packet_len)
276 if (!i_packet_len) /* 1st sanity check, we need at least the version */
277 return -1;
279 p_sig->version = *p_buf++;
281 size_t i_read;
282 switch (p_sig->version)
284 case 3:
285 i_read = parse_signature_v3_packet(p_sig, p_buf, i_packet_len);
286 break;
287 case 4:
288 p_sig->specific.v4.hashed_data = nullptr;
289 p_sig->specific.v4.unhashed_data = nullptr;
290 i_read = parse_signature_v4_packet(p_sig, p_buf, i_packet_len);
291 break;
292 default:
293 return -1;
296 if (i_read == 0) /* signature packet parsing has failed */
297 goto error;
299 if (!map_algo(p_sig->public_key_algo))
300 goto error;
302 if (!map_digestalgo(p_sig->digest_algo))
303 goto error;
305 switch (p_sig->type)
307 case BINARY_SIGNATURE:
308 case TEXT_SIGNATURE:
309 case GENERIC_KEY_SIGNATURE:
310 case PERSONA_KEY_SIGNATURE:
311 case CASUAL_KEY_SIGNATURE:
312 case POSITIVE_KEY_SIGNATURE:
313 break;
314 default:
315 goto error;
318 p_buf--; /* rewind to the version byte */
319 p_buf += i_read;
321 if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_DSA)
323 READ_MPI(p_sig->algo_specific.dsa.r, 160);
324 READ_MPI(p_sig->algo_specific.dsa.s, 160);
326 else if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_RSA)
327 READ_MPI(p_sig->algo_specific.rsa.s, 4096);
328 else
329 goto error;
331 ASSERT(i_read == i_packet_len);
332 if (i_read < i_packet_len) /* some extra data, hm ? */
333 goto error;
335 return 0;
337 error:
338 if (p_sig->version == 4)
340 free(p_sig->specific.v4.hashed_data);
341 free(p_sig->specific.v4.unhashed_data);
344 return -1;
348 * Transform an armored document in binary format
349 * Used on public keys and signatures
351 static int pgp_unarmor(const char *p_ibuf, size_t i_ibuf_len, uint8_t *p_obuf, size_t i_obuf_len)
353 const char *p_ipos = p_ibuf;
354 uint8_t *p_opos = p_obuf;
355 int i_end = 0;
356 int i_header_skipped = 0;
358 while (!i_end && p_ipos < p_ibuf + i_ibuf_len && *p_ipos != '=')
360 if (*p_ipos == '\r' || *p_ipos == '\n')
362 p_ipos++;
363 continue;
366 size_t i_line_len = strcspn(p_ipos, "\r\n");
367 if (i_line_len == 0)
368 continue;
370 if (!i_header_skipped)
372 if (!strncmp(p_ipos, "-----BEGIN PGP", 14))
373 i_header_skipped = 1;
375 p_ipos += i_line_len + 1;
376 continue;
379 if (!strncmp(p_ipos, "Version:", 8))
381 p_ipos += i_line_len + 1;
382 continue;
385 if (p_ipos[i_line_len - 1] == '=')
387 i_end = 1;
390 p_opos += b64_decode_binary_to_buffer(p_opos, p_obuf - p_opos + i_obuf_len, p_ipos, (int)i_line_len);
391 p_ipos += i_line_len + 1;
394 if (p_ipos + 1 < p_ibuf + i_ibuf_len && (*p_ipos == '\r' || *p_ipos == '\n'))
395 p_ipos++;
397 /* XXX: the CRC is OPTIONAL, really require it ? */
398 if (p_ipos + 5 > p_ibuf + i_ibuf_len || *p_ipos++ != '=')
399 return 0;
401 uint8_t p_crc[3];
402 if (b64_decode_binary_to_buffer(p_crc, sizeof(p_crc), p_ipos, 5) != 3)
403 return 0;
405 long l_crc = crc_octets(p_obuf, p_opos - p_obuf);
406 long l_crc2 = (0 << 24) + (p_crc[0] << 16) + (p_crc[1] << 8) + p_crc[2];
408 return (int)((l_crc2 == l_crc) ? p_opos - p_obuf : 0);
412 * fill a public_key_packet_t structure from public key packet data
413 * verify that it is a version 4 public key packet, using DSA or RSA
415 static int parse_public_key_packet(public_key_packet_t *p_key, const uint8_t *p_buf, size_t i_packet_len)
417 if (i_packet_len < 6)
418 return -1;
420 size_t i_read = 0;
422 p_key->version = *p_buf++; i_read++;
423 if (p_key->version != 4)
424 return -1;
426 /* XXX: warn when timestamp is > date ? */
427 memcpy(p_key->timestamp, p_buf, 4); p_buf += 4; i_read += 4;
429 p_key->algo = *p_buf++; i_read++;
430 if (p_key->algo == PUBLIC_KEY_ALGO_DSA)
432 if (i_packet_len > 418) // we only support 1024-bit DSA keys and SHA1 signatures, see verify_signature_dsa
433 return -1;
434 READ_MPI(p_key->sig.dsa.p, 1024);
435 READ_MPI(p_key->sig.dsa.q, 160);
436 READ_MPI(p_key->sig.dsa.g, 1024);
437 READ_MPI(p_key->sig.dsa.y, 1024);
439 else if (p_key->algo == PUBLIC_KEY_ALGO_RSA)
441 READ_MPI(p_key->sig.rsa.n, 4096);
442 READ_MPI(p_key->sig.rsa.e, 4096);
444 else
445 return -1;
447 if (i_read == i_packet_len)
448 return 0;
450 error:
451 return -1;
455 * fill a public_key_t with public key data, including:
456 * * public key packet
457 * * signature packet issued by key which long id is p_sig_issuer
458 * * user id packet
460 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)
462 const uint8_t *pos = p_key_data;
463 const uint8_t *max_pos = pos + i_key_len;
465 int i_status = 0;
466 #define PUBLIC_KEY_FOUND 0x01
467 #define USER_ID_FOUND 0x02
468 #define SIGNATURE_FOUND 0X04
470 uint8_t *p_key_unarmored = nullptr;
472 p_key->psz_username = nullptr;
473 p_key->sig.specific.v4.hashed_data = nullptr;
474 p_key->sig.specific.v4.unhashed_data = nullptr;
476 if (!(*pos & 0x80))
477 { /* first byte is ASCII, unarmoring */
478 p_key_unarmored = (uint8_t*)malloc(i_key_len);
479 if (!p_key_unarmored)
480 return -1;
481 int i_len = pgp_unarmor((char*)p_key_data, i_key_len, p_key_unarmored, i_key_len);
483 if (i_len == 0)
484 goto error;
486 pos = p_key_unarmored;
487 max_pos = pos + i_len;
490 while (pos < max_pos)
492 if (!(*pos & 0x80) || *pos & 0x40)
493 goto error;
495 int i_type = packet_type(*pos);
497 int i_header_len = packet_header_len(*pos++);
498 if (pos + i_header_len > max_pos || (i_header_len != 1 && i_header_len != 2 && i_header_len != 4))
499 goto error;
501 int i_packet_len = scalar_number(pos, i_header_len);
502 pos += i_header_len;
504 if (pos + i_packet_len > max_pos)
505 goto error;
507 switch (i_type)
509 case PUBLIC_KEY_PACKET:
510 i_status |= PUBLIC_KEY_FOUND;
511 if (parse_public_key_packet(&p_key->key, pos, i_packet_len) != 0)
512 goto error;
513 break;
515 case SIGNATURE_PACKET: /* we accept only v4 signatures here */
516 if (i_status & SIGNATURE_FOUND || !p_sig_issuer)
517 break;
518 if (parse_signature_packet(&p_key->sig, pos, i_packet_len) == 0)
520 if (p_key->sig.version != 4)
521 break;
522 if (memcmp( p_key->sig.issuer_longid, p_sig_issuer, 8))
524 free(p_key->sig.specific.v4.hashed_data);
525 free(p_key->sig.specific.v4.unhashed_data);
526 p_key->sig.specific.v4.hashed_data = nullptr;
527 p_key->sig.specific.v4.unhashed_data = nullptr;
528 break;
530 i_status |= SIGNATURE_FOUND;
532 break;
534 case USER_ID_PACKET:
535 if (p_key->psz_username) /* save only the first User ID */
536 break;
537 i_status |= USER_ID_FOUND;
538 p_key->psz_username = (uint8_t*)malloc(i_packet_len + 1);
539 if (!p_key->psz_username)
540 goto error;
542 memcpy(p_key->psz_username, pos, i_packet_len);
543 p_key->psz_username[i_packet_len] = '\0';
544 break;
546 default:
547 break;
549 pos += i_packet_len;
551 free(p_key_unarmored);
553 if (!(i_status & (PUBLIC_KEY_FOUND | USER_ID_FOUND)))
554 return -1;
556 if (p_sig_issuer && !(i_status & SIGNATURE_FOUND))
557 return -1;
559 return 0;
561 error:
562 if (p_key->sig.version == 4)
564 free(p_key->sig.specific.v4.hashed_data);
565 free(p_key->sig.specific.v4.unhashed_data);
567 free(p_key->psz_username);
568 free(p_key_unarmored);
569 return -1;
572 static int LoadSignature(const CString &signatureFilename, signature_packet_t *p_sig)
574 FILE * pFile = _tfsopen(signatureFilename, _T("rb"), SH_DENYWR);
575 if (pFile)
577 int size = 65536;
578 std::unique_ptr<unsigned char[]> buffer(new unsigned char[size]);
579 int length = 0;
580 if ((length = (int)fread(buffer.get(), sizeof(char), size, pFile)) >= 8)
582 fclose(pFile);
583 // is unpacking needed?
584 if ((uint8_t)buffer[0] < 0x80)
586 std::unique_ptr<unsigned char[]> unpacked(new unsigned char[size]);
587 size = pgp_unarmor((char *)buffer.get(), length, unpacked.get(), length);
589 if (size < 2)
590 return -1;
592 buffer.swap(unpacked);
594 else
595 size = length;
597 if (packet_type(buffer[0]) != SIGNATURE_PACKET)
598 return -1;
600 DWORD i_header_len = packet_header_len(buffer[0]);
601 if ((i_header_len != 1 && i_header_len != 2 && i_header_len != 4) || i_header_len + 1 > (DWORD)size)
602 return -1;
604 DWORD i_len = scalar_number((uint8_t *)(buffer.get() + 1), i_header_len);
605 if (i_len + i_header_len + 1 != (DWORD)size)
606 return -1;
608 if (parse_signature_packet(p_sig, (uint8_t *)(buffer.get() + 1 + i_header_len), i_len))
609 return -1;
611 if (p_sig->type != BINARY_SIGNATURE && p_sig->type != TEXT_SIGNATURE)
613 if (p_sig->version == 4)
615 free(p_sig->specific.v4.hashed_data);
616 free(p_sig->specific.v4.unhashed_data);
618 return -1;
621 return 0;
623 else
624 fclose(pFile);
626 return -1;
629 static void CryptHashChar(HCRYPTHASH hHash, const int c)
631 CryptHashData(hHash, (BYTE *)&c, 1, 0);
634 /* final part of the hash */
635 static int hash_finish(HCRYPTHASH hHash, signature_packet_t *p_sig)
637 if (p_sig->version == 3)
639 CryptHashChar(hHash, p_sig->type);
640 CryptHashData(hHash, (unsigned char*)&p_sig->specific.v3.timestamp, 4, 0);
642 else if (p_sig->version == 4)
644 CryptHashChar(hHash, p_sig->version);
645 CryptHashChar(hHash, p_sig->type);
646 CryptHashChar(hHash, p_sig->public_key_algo);
647 CryptHashChar(hHash, p_sig->digest_algo);
648 CryptHashData(hHash, p_sig->specific.v4.hashed_data_len, 2, 0);
649 unsigned int i_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
650 CryptHashData(hHash, p_sig->specific.v4.hashed_data, i_len, 0);
652 CryptHashChar(hHash, 0x04);
653 CryptHashChar(hHash, 0xFF);
655 i_len += 6; /* hashed data + 6 bytes header */
657 CryptHashChar(hHash, (i_len >> 24) & 0xff);
658 CryptHashChar(hHash, (i_len >> 16) & 0xff);
659 CryptHashChar(hHash, (i_len >> 8) & 0xff);
660 CryptHashChar(hHash, (i_len) & 0xff);
662 else
663 { /* RFC 4880 only tells about versions 3 and 4 */
664 return -1;
667 return 0;
671 * Generate a hash on a public key, to verify a signature made on that hash
672 * Note that we need the signature (v4) to compute the hash
674 static int hash_from_public_key(HCRYPTHASH hHash, public_key_t* p_pkey)
676 if (p_pkey->sig.version != 4)
677 return -1;
679 if (p_pkey->sig.type < GENERIC_KEY_SIGNATURE || p_pkey->sig.type > POSITIVE_KEY_SIGNATURE)
680 return -1;
682 DWORD i_size = 0;
683 unsigned int i_p_len = 0, i_g_len = 0, i_q_len = 0, i_y_len = 0;
684 unsigned int i_n_len = 0, i_e_len = 0;
686 if (p_pkey->key.algo == PUBLIC_KEY_ALGO_DSA)
688 i_p_len = mpi_len(p_pkey->key.sig.dsa.p);
689 i_g_len = mpi_len(p_pkey->key.sig.dsa.g);
690 i_q_len = mpi_len(p_pkey->key.sig.dsa.q);
691 i_y_len = mpi_len(p_pkey->key.sig.dsa.y);
693 i_size = 6 + 2 * 4 + i_p_len + i_g_len + i_q_len + i_y_len;
695 else if (p_pkey->key.algo == PUBLIC_KEY_ALGO_RSA)
697 i_n_len = mpi_len(p_pkey->key.sig.rsa.n);
698 i_e_len = mpi_len(p_pkey->key.sig.rsa.e);
700 i_size = 6 + 2 * 2 + i_n_len + i_e_len;
702 else
703 return -1;
705 CryptHashChar(hHash, 0x99);
707 CryptHashChar(hHash, (i_size >> 8) & 0xff);
708 CryptHashChar(hHash, i_size & 0xff);
710 CryptHashChar(hHash, p_pkey->key.version);
711 CryptHashData(hHash, p_pkey->key.timestamp, 4, 0);
712 CryptHashChar(hHash, p_pkey->key.algo);
714 if (p_pkey->key.algo == PUBLIC_KEY_ALGO_DSA)
716 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.p, 2 + i_p_len, 0);
717 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.q, 2 + i_q_len, 0);
718 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.g, 2 + i_g_len, 0);
719 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.y, 2 + i_y_len, 0);
721 else if (p_pkey->key.algo == PUBLIC_KEY_ALGO_RSA)
723 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.rsa.n, 2 + i_n_len, 0);
724 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.rsa.e, 2 + i_e_len, 0);
727 CryptHashChar(hHash, 0xb4);
729 size_t i_len = strlen((char *)p_pkey->psz_username);
731 CryptHashChar(hHash, (i_len >> 24) & 0xff);
732 CryptHashChar(hHash, (i_len >> 16) & 0xff);
733 CryptHashChar(hHash, (i_len >> 8) & 0xff);
734 CryptHashChar(hHash, (i_len) & 0xff);
736 CryptHashData(hHash, p_pkey->psz_username, (DWORD)i_len, 0);
738 return hash_finish(hHash, &p_pkey->sig);
741 static int hash_from_file(HCRYPTHASH hHash, CString filename, signature_packet_t* p_sig)
743 FILE * pFile = _tfsopen(filename, _T("rb"), SH_DENYWR);
744 if (!pFile)
745 return -1;
747 char buf[4097] = { 0 };
748 int read = 0;
749 int nlHandling = 0;
750 while ((read = (int)fread(buf, sizeof(char), sizeof(buf) - 1, pFile)) > 0)
752 if (p_sig->type == TEXT_SIGNATURE)
754 buf[read] = 0;
755 char * psz_string = buf;
756 while (*psz_string)
758 if (nlHandling == 1 && (*psz_string == '\r' || *psz_string == '\n'))
760 CryptHashChar(hHash, '\r');
761 CryptHashChar(hHash, '\n');
762 nlHandling = 2;
764 if (nlHandling == 2 && *psz_string == '\r')
766 psz_string++;
767 nlHandling = 2;
768 if (!*psz_string)
769 break;
772 if ((nlHandling == 2 || nlHandling == 3) && *psz_string == '\n')
774 psz_string++;
775 if (!*psz_string)
776 break;
779 size_t i_len = strcspn(psz_string, "\r\n");
781 if (i_len)
783 CryptHashData(hHash, (BYTE *)psz_string, (DWORD)i_len, 0);
784 psz_string += i_len;
787 nlHandling = 1;
788 if (*psz_string == '\r' || *psz_string == '\n')
790 CryptHashChar(hHash, '\r');
791 CryptHashChar(hHash, '\n');
792 nlHandling = 2;
794 if (*psz_string == '\r')
796 psz_string++;
797 nlHandling = 3;
800 if (*psz_string == '\n')
802 psz_string++;
803 nlHandling = 0;
808 else
809 CryptHashData(hHash, (BYTE *)buf, read, 0);
812 fclose(pFile);
814 return hash_finish(hHash, p_sig);
817 static int check_hash(HCRYPTHASH hHash, signature_packet_t *p_sig)
819 DWORD hashLen;
820 DWORD hashLenLen = sizeof(DWORD);
821 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &hashLenLen, 0))
822 return -1;
824 std::unique_ptr<BYTE[]> pHash(new BYTE[hashLen]);
825 CryptGetHashParam(hHash, HP_HASHVAL, pHash.get(), &hashLen, 0);
827 if (pHash.get()[0] != p_sig->hash_verification[0] || pHash.get()[1] != p_sig->hash_verification[1])
828 return -1;
830 return 0;
834 * Verify an OpenPGP signature made with some RSA public key
836 static int verify_signature_rsa(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_pkey, signature_packet_t& p_sig)
838 int i_n_len = min(mpi_len(p_pkey.key.sig.rsa.n), sizeof(p_pkey.key.sig.rsa.n) - 2);
839 int i_s_len = min(mpi_len(p_sig.algo_specific.rsa.s), sizeof(p_sig.algo_specific.rsa.s) - 2);
841 if (i_s_len > i_n_len)
842 return -1;
844 RSAKEY rsakey;
845 rsakey.blobheader.bType = PUBLICKEYBLOB; // 0x06
846 rsakey.blobheader.bVersion = CUR_BLOB_VERSION; // 0x02
847 rsakey.blobheader.reserved = 0;
848 rsakey.blobheader.aiKeyAlg = CALG_RSA_KEYX;
849 rsakey.rsapubkey.magic = 0x31415352;// ASCII for RSA1
850 rsakey.rsapubkey.bitlen = i_n_len * 8;
851 rsakey.rsapubkey.pubexp = 65537; // gnupg only uses this
853 memcpy(rsakey.n, p_pkey.key.sig.rsa.n + 2, i_n_len); std::reverse(rsakey.n, rsakey.n + i_n_len);
855 HCRYPTKEY hPubKey;
856 if (CryptImportKey(hCryptProv, (BYTE*)&rsakey, sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + i_n_len, 0, 0, &hPubKey) == 0)
857 return -1;
859 /* i_s_len might be shorter than i_n_len,
860 * but CrytoAPI requires that both have same length,
861 * thus, use i_n_len as buffer length (pSig; it's safe as i_n_len cannot be longer than the buffer),
862 * but do not copy/reverse NULs at the end of p_sig.algo_specific.rsa.s into pSig
864 std::unique_ptr<BYTE[]> pSig(new BYTE[i_n_len]);
865 SecureZeroMemory(pSig.get(), i_n_len);
866 memcpy(pSig.get(), p_sig.algo_specific.rsa.s + 2, i_s_len);
867 std::reverse(pSig.get(), pSig.get() + i_s_len);
868 if (!CryptVerifySignature(hHash, pSig.get(), i_n_len, hPubKey, nullptr, 0))
870 CryptDestroyKey(hPubKey);
871 return -1;
874 CryptDestroyKey(hPubKey);
875 return 0;
879 * Verify an OpenPGP signature made with some DSA public key
881 static int verify_signature_dsa(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_pkey, signature_packet_t& p_sig)
883 if (p_sig.digest_algo != DIGEST_ALGO_SHA1) // PROV_DSS only supports SHA1 signatures, see http://msdn.microsoft.com/en-us/library/windows/desktop/aa387434%28v=vs.85%29.aspx
884 return -1;
886 HCRYPTKEY hPubKey;
887 // based on http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-10/0040.html
888 DSAKEY dsakey;
889 dsakey.blobheader.bType = PUBLICKEYBLOB; // 0x06
890 dsakey.blobheader.bVersion = CUR_BLOB_VERSION + 1; // 0x03
891 dsakey.blobheader.reserved = 0;
892 dsakey.blobheader.aiKeyAlg = CALG_DSS_SIGN;
893 dsakey.dsspubkeyver3.magic = 0x33535344; // ASCII of "DSS3";
894 dsakey.dsspubkeyver3.bitlenP = 1024; // # of bits in prime modulus
895 dsakey.dsspubkeyver3.bitlenQ = 160; // # of bits in prime q, 0 if not available
896 dsakey.dsspubkeyver3.bitlenJ = 0; // # of bits in (p-1)/q, 0 if not available
897 dsakey.dsspubkeyver3.DSSSeed.counter = 0xFFFFFFFF; // not available
899 memcpy(dsakey.p, p_pkey.key.sig.dsa.p + 2, sizeof(p_pkey.key.sig.dsa.p) - 2); std::reverse(dsakey.p, dsakey.p + sizeof(dsakey.p));
900 memcpy(dsakey.q, p_pkey.key.sig.dsa.q + 2, sizeof(p_pkey.key.sig.dsa.q) - 2); std::reverse(dsakey.q, dsakey.q + sizeof(dsakey.q));
901 memcpy(dsakey.g, p_pkey.key.sig.dsa.g + 2, sizeof(p_pkey.key.sig.dsa.g) - 2); std::reverse(dsakey.g, dsakey.g + sizeof(dsakey.g));
902 memcpy(dsakey.y, p_pkey.key.sig.dsa.y + 2, sizeof(p_pkey.key.sig.dsa.y) - 2); std::reverse(dsakey.y, dsakey.y + sizeof(dsakey.y));
904 if (CryptImportKey(hCryptProv, (BYTE*)&dsakey, sizeof(dsakey), 0, 0, &hPubKey) == 0)
905 return -1;
907 unsigned char signature[40] = { 0 };
908 memcpy(signature, p_sig.algo_specific.dsa.r + 2, 20);
909 memcpy(signature + 20, p_sig.algo_specific.dsa.s + 2, 20);
910 std::reverse(signature, signature + 20);
911 std::reverse(signature + 20, signature + 40);
912 if (!CryptVerifySignature(hHash, signature, sizeof(signature), hPubKey, nullptr, 0))
914 CryptDestroyKey(hPubKey);
915 return -1;
918 CryptDestroyKey(hPubKey);
919 return 0;
923 * Verify an OpenPGP signature made with some public key
925 int verify_signature(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_key, signature_packet_t& sign)
927 if (sign.public_key_algo == PUBLIC_KEY_ALGO_DSA)
928 return verify_signature_dsa(hCryptProv, hHash, p_key, sign);
929 else if (sign.public_key_algo == PUBLIC_KEY_ALGO_RSA)
930 return verify_signature_rsa(hCryptProv, hHash, p_key, sign);
931 else
932 return -1;
936 * download a public key (the last one) from TortoiseGit server, and parse it
938 static public_key_t *download_key(const uint8_t *p_longid, const uint8_t *p_signature_issuer, CUpdateDownloader *updateDownloader)
940 ASSERT(updateDownloader);
942 CString url;
943 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]);
945 CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
946 if (updateDownloader->DownloadFile(url, tempfile, false))
947 return nullptr;
949 int size = 65536;
950 std::unique_ptr<char[]> buffer(new char[size]);
951 FILE * pFile = _tfsopen(tempfile, _T("rb"), SH_DENYWR);
952 if (pFile)
954 int length = 0;
955 if ((length = (int)fread(buffer.get(), sizeof(char), size, pFile)) >= 8)
957 fclose(pFile);
958 size = length;
960 else
962 fclose(pFile);
963 return nullptr;
966 else
967 return nullptr;
969 public_key_t *p_pkey = (public_key_t*) malloc(sizeof(public_key_t));
970 if (!p_pkey)
972 DeleteUrlCacheEntry(url);
973 return nullptr;
976 memcpy(p_pkey->longid, p_longid, 8);
978 if (parse_public_key((const uint8_t *)buffer.get(), size, p_pkey, p_signature_issuer))
980 free(p_pkey);
981 return nullptr;
984 return p_pkey;
987 int VerifyIntegrity(const CString &filename, const CString &signatureFilename, CUpdateDownloader *updateDownloader)
989 ASSERT(updateDownloader);
991 signature_packet_t p_sig;
992 memset(&p_sig, 0, sizeof(signature_packet_t));
993 if (LoadSignature(signatureFilename, &p_sig))
994 return -1;
996 public_key_t p_pkey;
997 memset(&p_pkey, 0, sizeof(public_key_t));
998 if (parse_public_key(tortoisegit_public_key, sizeof(tortoisegit_public_key), &p_pkey, nullptr))
1000 if (p_sig.version == 4)
1002 free(p_sig.specific.v4.hashed_data);
1003 free(p_sig.specific.v4.unhashed_data);
1005 return -1;
1007 memcpy(p_pkey.longid, tortoisegit_public_key_longid, 8);
1009 HCRYPTPROV hCryptProv;
1010 if (!CryptAcquireContext(&hCryptProv, nullptr, nullptr, map_algo(p_pkey.key.algo), CRYPT_VERIFYCONTEXT))
1012 if (p_sig.version == 4)
1014 free(p_sig.specific.v4.hashed_data);
1015 free(p_sig.specific.v4.unhashed_data);
1017 free(p_pkey.psz_username);
1018 return -1;
1021 if (memcmp(p_sig.issuer_longid, p_pkey.longid, 8) != 0)
1023 public_key_t *p_new_pkey = download_key(p_sig.issuer_longid, tortoisegit_public_key_longid, updateDownloader);
1024 if (!p_new_pkey)
1026 if (p_sig.version == 4)
1028 free(p_sig.specific.v4.hashed_data);
1029 free(p_sig.specific.v4.unhashed_data);
1031 free(p_pkey.psz_username);
1032 CryptReleaseContext(hCryptProv, 0);
1033 return -1;
1036 HCRYPTHASH hHash;
1037 if (!CryptCreateHash(hCryptProv, map_digestalgo(p_sig.digest_algo), 0, 0, &hHash))
1039 if (p_sig.version == 4)
1041 free(p_sig.specific.v4.hashed_data);
1042 free(p_sig.specific.v4.unhashed_data);
1044 free(p_pkey.psz_username);
1045 CryptReleaseContext(hCryptProv, 0);
1046 free(p_new_pkey->psz_username);
1047 if (p_new_pkey->sig.version == 4)
1049 free(p_new_pkey->sig.specific.v4.hashed_data);
1050 free(p_new_pkey->sig.specific.v4.unhashed_data);
1052 free(p_new_pkey);
1053 return -1;
1056 if (hash_from_public_key(hHash, p_new_pkey))
1058 if (p_sig.version == 4)
1060 free(p_sig.specific.v4.hashed_data);
1061 free(p_sig.specific.v4.unhashed_data);
1063 free(p_pkey.psz_username);
1064 CryptReleaseContext(hCryptProv, 0);
1065 free(p_new_pkey->psz_username);
1066 if (p_new_pkey->sig.version == 4)
1068 free(p_new_pkey->sig.specific.v4.hashed_data);
1069 free(p_new_pkey->sig.specific.v4.unhashed_data);
1071 free(p_new_pkey);
1072 CryptDestroyHash(hHash);
1073 return -1;
1076 if (check_hash(hHash, &p_new_pkey->sig))
1078 if (p_sig.version == 4)
1080 free(p_sig.specific.v4.hashed_data);
1081 free(p_sig.specific.v4.unhashed_data);
1083 free(p_pkey.psz_username);
1084 CryptReleaseContext(hCryptProv, 0);
1085 free(p_new_pkey->psz_username);
1086 if (p_new_pkey->sig.version == 4)
1088 free(p_new_pkey->sig.specific.v4.hashed_data);
1089 free(p_new_pkey->sig.specific.v4.unhashed_data);
1091 free(p_new_pkey);
1092 CryptDestroyHash(hHash);
1093 return -1;
1096 if (verify_signature(hCryptProv, hHash, p_pkey, p_new_pkey->sig))
1098 if (p_sig.version == 4)
1100 free(p_sig.specific.v4.hashed_data);
1101 free(p_sig.specific.v4.unhashed_data);
1103 free(p_pkey.psz_username);
1104 CryptReleaseContext(hCryptProv, 0);
1105 free(p_new_pkey->psz_username);
1106 if (p_new_pkey->sig.version == 4)
1108 free(p_new_pkey->sig.specific.v4.hashed_data);
1109 free(p_new_pkey->sig.specific.v4.unhashed_data);
1111 free(p_new_pkey);
1112 CryptDestroyHash(hHash);
1113 return -1;
1115 else
1117 CryptDestroyHash(hHash);
1118 free(p_pkey.psz_username);
1119 p_pkey = *p_new_pkey;
1120 if (p_pkey.sig.version == 4)
1122 p_pkey.sig.version = 0;
1123 free(p_pkey.sig.specific.v4.hashed_data);
1124 free(p_pkey.sig.specific.v4.unhashed_data);
1126 free(p_new_pkey);
1130 int nRetCode = -1;
1132 HCRYPTHASH hHash;
1133 if (!CryptCreateHash(hCryptProv, map_digestalgo(p_sig.digest_algo), 0, 0, &hHash))
1134 goto error;
1136 if (hash_from_file(hHash, filename, &p_sig))
1137 goto error;
1139 if (check_hash(hHash, &p_sig))
1140 goto error;
1142 if (verify_signature(hCryptProv, hHash, p_pkey, p_sig))
1143 goto error;
1145 nRetCode = 0;
1147 error:
1148 CryptDestroyHash(hHash);
1149 CryptReleaseContext(hCryptProv, 0);
1151 free(p_pkey.psz_username);
1152 if (p_sig.version == 4)
1154 free(p_sig.specific.v4.hashed_data);
1155 free(p_sig.specific.v4.unhashed_data);
1158 return nRetCode;