Don't import ogdf namespace
[TortoiseGit.git] / src / TortoiseProc / UpdateCrypto.cpp
blobcbc3d1f7377190a7d35c9694a70bca3f3830369f
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013-2017 Sven Strickroth <email@cs-ware.de>
4 // Copyright (C) 2014-2017 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"
31 #include "SmartHandle.h"
33 #define packet_type(c) ((c & 0x3c) >> 2) /* 0x3C = 00111100 */
34 #define packet_header_len(c) ((c & 0x03) + 1) /* number of bytes in a packet header */
36 static inline int scalar_number(const uint8_t *p, int header_len)
38 ASSERT(header_len == 1 || header_len == 2 || header_len == 4);
40 if (header_len == 1)
41 return p[0];
42 else if (header_len == 2)
43 return (p[0] << 8) + p[1];
44 else if (header_len == 4)
45 return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
46 else
47 abort();
50 /* number of data bytes in a MPI */
51 static int mpi_len(const uint8_t* mpi)
53 return (scalar_number(mpi, 2) + 7) / 8;
56 static size_t read_mpi(uint8_t* dst, const uint8_t* buf, size_t buflen, size_t bits)
58 if (buflen < 2)
59 return 0;
61 size_t n = mpi_len(buf);
63 if (n * 8 > bits)
64 return 0;
66 n += 2;
68 if (buflen < n)
69 return 0;
71 memcpy(dst, buf, n);
72 return n;
75 #define READ_MPI(d, bits) do \
76 { \
77 size_t n = read_mpi(d, p_buf, i_packet_len - i_read, bits); \
78 if (!n) goto error; \
79 p_buf += n; \
80 i_read += n; \
81 } while(0)
83 /* Base64 decoding */
84 static size_t b64_decode_binary_to_buffer(uint8_t *p_dst, size_t i_dst, const char *p_src, size_t srcLen)
86 int len = (int)i_dst;
87 if (!Base64Decode(p_src, (int)srcLen, p_dst, &len))
88 return 0;
89 return len;
93 * crc_octets() was lamely copied from rfc 2440
94 * Copyright (C) The Internet Society (1998). All Rights Reserved.
96 #define CRC24_INIT 0xB704CEL
97 #define CRC24_POLY 0x1864CFBL
99 static long crc_octets(uint8_t *octets, size_t len)
101 long crc = CRC24_INIT;
102 int i;
103 while (len--)
105 crc ^= (*octets++) << 16;
106 for (i = 0; i < 8; i++)
108 crc <<= 1;
109 if (crc & 0x1000000)
110 crc ^= CRC24_POLY;
113 return crc & 0xFFFFFFL;
116 static ALG_ID map_digestalgo(uint8_t digest_algo)
118 switch (digest_algo)
120 case DIGEST_ALGO_SHA1:
121 return CALG_SHA1;
122 case DIGEST_ALGO_SHA256:
123 return CALG_SHA_256;
124 case DIGEST_ALGO_SHA384:
125 return CALG_SHA_384;
126 case DIGEST_ALGO_SHA512:
127 return CALG_SHA_512;
128 default:
129 return 0;
133 static DWORD map_algo(uint8_t digest_algo)
135 switch (digest_algo)
137 case PUBLIC_KEY_ALGO_DSA:
138 return PROV_DSS;
139 case PUBLIC_KEY_ALGO_RSA:
140 return PROV_RSA_AES; // needed for SHA2, see http://msdn.microsoft.com/en-us/library/windows/desktop/aa387447%28v=vs.85%29.aspx
141 default:
142 return 0;
146 static size_t parse_signature_v3_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
148 size_t i_read = 1; /* we already read the version byte */
150 if (i_sig_len < 19) /* signature is at least 19 bytes + the 2 MPIs */
151 return 0;
153 p_sig->specific.v3.hashed_data_len = *p_buf++; i_read++;
154 if (p_sig->specific.v3.hashed_data_len != 5)
155 return 0;
157 p_sig->type = *p_buf++; i_read++;
159 memcpy(p_sig->specific.v3.timestamp, p_buf, 4);
160 p_buf += 4; i_read += 4;
162 memcpy(p_sig->issuer_longid, p_buf, 8);
163 p_buf += 8; i_read += 8;
165 p_sig->public_key_algo = *p_buf++; i_read++;
167 p_sig->digest_algo = *p_buf++; i_read++;
169 p_sig->hash_verification[0] = *p_buf++; i_read++;
170 p_sig->hash_verification[1] = *p_buf++; i_read++;
172 if (i_read != 19)
173 return 0;
175 return i_read;
179 * fill a signature_packet_v4_t from signature packet data
180 * verify that it was used with a DSA or RSA public key
182 static size_t parse_signature_v4_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_sig_len)
184 size_t i_read = 1; /* we already read the version byte */
186 if (i_sig_len < 10) /* signature is at least 10 bytes + the 2 MPIs */
187 return 0;
189 p_sig->type = *p_buf++; i_read++;
191 p_sig->public_key_algo = *p_buf++; i_read++;
193 p_sig->digest_algo = *p_buf++; i_read++;
194 if (!map_algo(p_sig->public_key_algo))
195 return 0;
197 memcpy(p_sig->specific.v4.hashed_data_len, p_buf, 2);
198 p_buf += 2; i_read += 2;
200 size_t i_hashed_data_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
201 i_read += i_hashed_data_len;
202 if (i_read + 4 > i_sig_len || i_hashed_data_len > i_sig_len)
203 return 0;
205 p_sig->specific.v4.hashed_data = (uint8_t*) malloc(i_hashed_data_len);
206 if (!p_sig->specific.v4.hashed_data)
207 return 0;
208 memcpy(p_sig->specific.v4.hashed_data, p_buf, i_hashed_data_len);
209 p_buf += i_hashed_data_len;
211 memcpy(p_sig->specific.v4.unhashed_data_len, p_buf, 2);
212 p_buf += 2; i_read += 2;
214 size_t i_unhashed_data_len = scalar_number(p_sig->specific.v4.unhashed_data_len, 2);
215 i_read += i_unhashed_data_len;
216 if (i_read + 2 > i_sig_len || i_unhashed_data_len > i_sig_len)
217 return 0;
219 p_sig->specific.v4.unhashed_data = (uint8_t*) malloc(i_unhashed_data_len);
220 if (!p_sig->specific.v4.unhashed_data)
221 return 0;
223 memcpy(p_sig->specific.v4.unhashed_data, p_buf, i_unhashed_data_len);
224 p_buf += i_unhashed_data_len;
226 memcpy(p_sig->hash_verification, p_buf, 2);
227 p_buf += 2; i_read += 2;
229 uint8_t *p, *max_pos;
230 p = p_sig->specific.v4.unhashed_data;
231 max_pos = p + i_unhashed_data_len;
233 for (;;)
235 if (p > max_pos)
236 return 0;
238 size_t i_subpacket_len;
239 if (*p < 192)
241 if (p + 1 > max_pos)
242 return 0;
243 i_subpacket_len = *p++;
245 else if (*p < 255)
247 if (p + 2 > max_pos)
248 return 0;
249 i_subpacket_len = ((size_t)(*p++ - 192)) << 8;
250 i_subpacket_len += *p++ + 192;
252 else
254 if (p + 4 > max_pos)
255 return 0;
256 i_subpacket_len = size_t(*++p) << 24;
257 i_subpacket_len += ((size_t)*++p) << 16;
258 i_subpacket_len += ((size_t)++p) << 8;
259 i_subpacket_len += *++p;
262 if (*p == ISSUER_SUBPACKET)
264 if (p + 9 > max_pos)
265 return 0;
267 memcpy(&p_sig->issuer_longid, p + 1, 8);
269 return i_read;
272 if (i_subpacket_len > i_unhashed_data_len)
273 return 0;
275 p += i_subpacket_len;
279 static int parse_signature_packet(signature_packet_t *p_sig, const uint8_t *p_buf, size_t i_packet_len)
281 if (!i_packet_len) /* 1st sanity check, we need at least the version */
282 return -1;
284 p_sig->version = *p_buf++;
286 size_t i_read;
287 switch (p_sig->version)
289 case 3:
290 i_read = parse_signature_v3_packet(p_sig, p_buf, i_packet_len);
291 break;
292 case 4:
293 p_sig->specific.v4.hashed_data = nullptr;
294 p_sig->specific.v4.unhashed_data = nullptr;
295 i_read = parse_signature_v4_packet(p_sig, p_buf, i_packet_len);
296 break;
297 default:
298 return -1;
301 if (i_read == 0) /* signature packet parsing has failed */
302 goto error;
304 if (!map_algo(p_sig->public_key_algo))
305 goto error;
307 if (!map_digestalgo(p_sig->digest_algo))
308 goto error;
310 switch (p_sig->type)
312 case BINARY_SIGNATURE:
313 case TEXT_SIGNATURE:
314 case GENERIC_KEY_SIGNATURE:
315 case PERSONA_KEY_SIGNATURE:
316 case CASUAL_KEY_SIGNATURE:
317 case POSITIVE_KEY_SIGNATURE:
318 break;
319 default:
320 goto error;
323 p_buf--; /* rewind to the version byte */
324 p_buf += i_read;
326 if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_DSA)
328 READ_MPI(p_sig->algo_specific.dsa.r, 160);
329 READ_MPI(p_sig->algo_specific.dsa.s, 160);
331 else if (p_sig->public_key_algo == PUBLIC_KEY_ALGO_RSA)
332 READ_MPI(p_sig->algo_specific.rsa.s, 4096);
333 else
334 goto error;
336 if (i_read != i_packet_len)
337 goto error;
339 return 0;
341 error:
342 if (p_sig->version == 4)
344 free(p_sig->specific.v4.hashed_data);
345 free(p_sig->specific.v4.unhashed_data);
348 return -1;
352 * Transform an armored document in binary format
353 * Used on public keys and signatures
355 static int pgp_unarmor(const char *p_ibuf, size_t i_ibuf_len, uint8_t *p_obuf, size_t i_obuf_len)
357 const char *p_ipos = p_ibuf;
358 uint8_t *p_opos = p_obuf;
359 int i_end = 0;
360 int i_header_skipped = 0;
362 while (!i_end && p_ipos < p_ibuf + i_ibuf_len && *p_ipos != '=')
364 if (*p_ipos == '\r' || *p_ipos == '\n')
366 p_ipos++;
367 continue;
370 size_t i_line_len = strcspn(p_ipos, "\r\n");
371 if (i_line_len == 0)
372 continue;
374 if (!i_header_skipped)
376 if (!strncmp(p_ipos, "-----BEGIN PGP", 14))
377 i_header_skipped = 1;
379 p_ipos += i_line_len + 1;
380 continue;
383 if (!strncmp(p_ipos, "Version:", 8))
385 p_ipos += i_line_len + 1;
386 continue;
389 if (p_ipos[i_line_len - 1] == '=')
391 i_end = 1;
394 p_opos += b64_decode_binary_to_buffer(p_opos, p_obuf - p_opos + i_obuf_len, p_ipos, (int)i_line_len);
395 p_ipos += i_line_len + 1;
398 if (p_ipos + 1 < p_ibuf + i_ibuf_len && (*p_ipos == '\r' || *p_ipos == '\n'))
399 p_ipos++;
401 /* XXX: the CRC is OPTIONAL, really require it ? */
402 if (p_ipos + 5 > p_ibuf + i_ibuf_len || *p_ipos++ != '=')
403 return 0;
405 uint8_t p_crc[3];
406 if (b64_decode_binary_to_buffer(p_crc, sizeof(p_crc), p_ipos, 5) != 3)
407 return 0;
409 long l_crc = crc_octets(p_obuf, p_opos - p_obuf);
410 long l_crc2 = (0 << 24) + (p_crc[0] << 16) + (p_crc[1] << 8) + p_crc[2];
412 return (int)((l_crc2 == l_crc) ? p_opos - p_obuf : 0);
416 * fill a public_key_packet_t structure from public key packet data
417 * verify that it is a version 4 public key packet, using DSA or RSA
419 static int parse_public_key_packet(public_key_packet_t *p_key, const uint8_t *p_buf, size_t i_packet_len)
421 if (i_packet_len < 6)
422 return -1;
424 size_t i_read = 0;
426 p_key->version = *p_buf++; i_read++;
427 if (p_key->version != 4)
428 return -1;
430 /* XXX: warn when timestamp is > date ? */
431 memcpy(p_key->timestamp, p_buf, 4); p_buf += 4; i_read += 4;
433 p_key->algo = *p_buf++; i_read++;
434 if (p_key->algo == PUBLIC_KEY_ALGO_DSA)
436 if (i_packet_len > 418) // we only support 1024-bit DSA keys and SHA1 signatures, see verify_signature_dsa
437 return -1;
438 READ_MPI(p_key->sig.dsa.p, 1024);
439 READ_MPI(p_key->sig.dsa.q, 160);
440 READ_MPI(p_key->sig.dsa.g, 1024);
441 READ_MPI(p_key->sig.dsa.y, 1024);
443 else if (p_key->algo == PUBLIC_KEY_ALGO_RSA)
445 READ_MPI(p_key->sig.rsa.n, 4096);
446 READ_MPI(p_key->sig.rsa.e, 4096);
448 else
449 return -1;
451 if (i_read == i_packet_len)
452 return 0;
454 error:
455 return -1;
459 * fill a public_key_t with public key data, including:
460 * * public key packet
461 * * signature packet issued by key which long id is p_sig_issuer
462 * * user id packet
464 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)
466 const uint8_t *pos = p_key_data;
467 const uint8_t *max_pos = pos + i_key_len;
469 int i_status = 0;
470 #define PUBLIC_KEY_FOUND 0x01
471 #define USER_ID_FOUND 0x02
472 #define SIGNATURE_FOUND 0X04
474 uint8_t *p_key_unarmored = nullptr;
476 p_key->psz_username = nullptr;
477 p_key->sig.specific.v4.hashed_data = nullptr;
478 p_key->sig.specific.v4.unhashed_data = nullptr;
480 if (!(*pos & 0x80))
481 { /* first byte is ASCII, unarmoring */
482 p_key_unarmored = (uint8_t*)malloc(i_key_len);
483 if (!p_key_unarmored)
484 return -1;
485 int i_len = pgp_unarmor((char*)p_key_data, i_key_len, p_key_unarmored, i_key_len);
487 if (i_len == 0)
488 goto error;
490 pos = p_key_unarmored;
491 max_pos = pos + i_len;
494 while (pos < max_pos)
496 if (!(*pos & 0x80) || *pos & 0x40)
497 goto error;
499 int i_type = packet_type(*pos);
501 int i_header_len = packet_header_len(*pos++);
502 if (pos + i_header_len > max_pos || (i_header_len != 1 && i_header_len != 2 && i_header_len != 4))
503 goto error;
505 int i_packet_len = scalar_number(pos, i_header_len);
506 pos += i_header_len;
508 if (pos + i_packet_len > max_pos || i_packet_len < 0 || (size_t)i_packet_len > i_key_len)
509 goto error;
511 switch (i_type)
513 case PUBLIC_KEY_PACKET:
514 i_status |= PUBLIC_KEY_FOUND;
515 if (parse_public_key_packet(&p_key->key, pos, i_packet_len) != 0)
516 goto error;
517 break;
519 case SIGNATURE_PACKET: /* we accept only v4 signatures here */
520 if (i_status & SIGNATURE_FOUND || !p_sig_issuer)
521 break;
522 if (parse_signature_packet(&p_key->sig, pos, i_packet_len) == 0)
524 if (p_key->sig.version != 4)
525 break;
526 if (memcmp( p_key->sig.issuer_longid, p_sig_issuer, 8))
528 free(p_key->sig.specific.v4.hashed_data);
529 free(p_key->sig.specific.v4.unhashed_data);
530 p_key->sig.specific.v4.hashed_data = nullptr;
531 p_key->sig.specific.v4.unhashed_data = nullptr;
532 break;
534 i_status |= SIGNATURE_FOUND;
536 break;
538 case USER_ID_PACKET:
539 if (p_key->psz_username) /* save only the first User ID */
540 break;
541 i_status |= USER_ID_FOUND;
542 p_key->psz_username = (uint8_t*)malloc(i_packet_len + 1);
543 if (!p_key->psz_username)
544 goto error;
546 memcpy(p_key->psz_username, pos, i_packet_len);
547 p_key->psz_username[i_packet_len] = '\0';
548 break;
550 default:
551 break;
553 pos += i_packet_len;
555 free(p_key_unarmored);
557 if (!(i_status & (PUBLIC_KEY_FOUND | USER_ID_FOUND)))
558 return -1;
560 if (p_sig_issuer && !(i_status & SIGNATURE_FOUND))
561 return -1;
563 return 0;
565 error:
566 if (p_key->sig.version == 4)
568 free(p_key->sig.specific.v4.hashed_data);
569 free(p_key->sig.specific.v4.unhashed_data);
571 free(p_key->psz_username);
572 free(p_key_unarmored);
573 return -1;
576 static int LoadSignature(const CString &signatureFilename, signature_packet_t *p_sig)
578 FILE* pFile = _wfsopen(signatureFilename, L"rb", SH_DENYWR);
579 if (!pFile)
580 return -1;
582 int size = 65536;
583 auto buffer = std::make_unique<unsigned char[]>(size);
584 int length = (int)fread(buffer.get(), sizeof(char), size, pFile);
585 fclose(pFile);
586 if (length < 8)
587 return -1;
589 // is unpacking needed?
590 if ((uint8_t)buffer[0] < 0x80)
592 auto unpacked = std::make_unique<unsigned char[]>(size);
593 size = pgp_unarmor((char *)buffer.get(), length, unpacked.get(), length);
595 if (size < 2)
596 return -1;
598 buffer.swap(unpacked);
600 else
601 size = length;
603 if (packet_type(buffer[0]) != SIGNATURE_PACKET)
604 return -1;
606 DWORD i_header_len = packet_header_len(buffer[0]);
607 if ((i_header_len != 1 && i_header_len != 2 && i_header_len != 4) || i_header_len + 1 > (DWORD)size)
608 return -1;
610 DWORD i_len = scalar_number((uint8_t *)(buffer.get() + 1), i_header_len);
611 if (i_len + i_header_len + 1 != (DWORD)size)
612 return -1;
614 if (parse_signature_packet(p_sig, (uint8_t *)(buffer.get() + 1 + i_header_len), i_len))
615 return -1;
617 if (p_sig->type != BINARY_SIGNATURE && p_sig->type != TEXT_SIGNATURE)
619 if (p_sig->version == 4)
621 free(p_sig->specific.v4.hashed_data);
622 free(p_sig->specific.v4.unhashed_data);
624 return -1;
627 return 0;
630 static void CryptHashChar(HCRYPTHASH hHash, const int c)
632 CryptHashData(hHash, (BYTE *)&c, 1, 0);
635 /* final part of the hash */
636 static int hash_finish(HCRYPTHASH hHash, signature_packet_t *p_sig)
638 if (p_sig->version == 3)
640 CryptHashChar(hHash, p_sig->type);
641 CryptHashData(hHash, (unsigned char*)&p_sig->specific.v3.timestamp, 4, 0);
643 else if (p_sig->version == 4)
645 CryptHashChar(hHash, p_sig->version);
646 CryptHashChar(hHash, p_sig->type);
647 CryptHashChar(hHash, p_sig->public_key_algo);
648 CryptHashChar(hHash, p_sig->digest_algo);
649 CryptHashData(hHash, p_sig->specific.v4.hashed_data_len, 2, 0);
650 unsigned int i_len = scalar_number(p_sig->specific.v4.hashed_data_len, 2);
651 CryptHashData(hHash, p_sig->specific.v4.hashed_data, i_len, 0);
653 CryptHashChar(hHash, 0x04);
654 CryptHashChar(hHash, 0xFF);
656 i_len += 6; /* hashed data + 6 bytes header */
658 CryptHashChar(hHash, (i_len >> 24) & 0xff);
659 CryptHashChar(hHash, (i_len >> 16) & 0xff);
660 CryptHashChar(hHash, (i_len >> 8) & 0xff);
661 CryptHashChar(hHash, (i_len) & 0xff);
663 else
664 { /* RFC 4880 only tells about versions 3 and 4 */
665 return -1;
668 return 0;
672 * Generate a hash on a public key, to verify a signature made on that hash
673 * Note that we need the signature (v4) to compute the hash
675 static int hash_from_public_key(HCRYPTHASH hHash, public_key_t* p_pkey)
677 if (p_pkey->sig.version != 4)
678 return -1;
680 if (p_pkey->sig.type < GENERIC_KEY_SIGNATURE || p_pkey->sig.type > POSITIVE_KEY_SIGNATURE)
681 return -1;
683 DWORD i_size = 0;
684 unsigned int i_p_len = 0, i_g_len = 0, i_q_len = 0, i_y_len = 0;
685 unsigned int i_n_len = 0, i_e_len = 0;
687 if (p_pkey->key.algo == PUBLIC_KEY_ALGO_DSA)
689 i_p_len = mpi_len(p_pkey->key.sig.dsa.p);
690 i_g_len = mpi_len(p_pkey->key.sig.dsa.g);
691 i_q_len = mpi_len(p_pkey->key.sig.dsa.q);
692 i_y_len = mpi_len(p_pkey->key.sig.dsa.y);
694 i_size = 6 + 2 * 4 + i_p_len + i_g_len + i_q_len + i_y_len;
696 else if (p_pkey->key.algo == PUBLIC_KEY_ALGO_RSA)
698 i_n_len = mpi_len(p_pkey->key.sig.rsa.n);
699 i_e_len = mpi_len(p_pkey->key.sig.rsa.e);
701 i_size = 6 + 2 * 2 + i_n_len + i_e_len;
703 else
704 return -1;
706 CryptHashChar(hHash, 0x99);
708 CryptHashChar(hHash, (i_size >> 8) & 0xff);
709 CryptHashChar(hHash, i_size & 0xff);
711 CryptHashChar(hHash, p_pkey->key.version);
712 CryptHashData(hHash, p_pkey->key.timestamp, 4, 0);
713 CryptHashChar(hHash, p_pkey->key.algo);
715 if (p_pkey->key.algo == PUBLIC_KEY_ALGO_DSA)
717 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.p, 2 + i_p_len, 0);
718 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.q, 2 + i_q_len, 0);
719 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.g, 2 + i_g_len, 0);
720 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.dsa.y, 2 + i_y_len, 0);
722 else if (p_pkey->key.algo == PUBLIC_KEY_ALGO_RSA)
724 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.rsa.n, 2 + i_n_len, 0);
725 CryptHashData(hHash, (uint8_t*)&p_pkey->key.sig.rsa.e, 2 + i_e_len, 0);
728 CryptHashChar(hHash, 0xb4);
730 size_t i_len = strlen((char *)p_pkey->psz_username);
732 CryptHashChar(hHash, (i_len >> 24) & 0xff);
733 CryptHashChar(hHash, (i_len >> 16) & 0xff);
734 CryptHashChar(hHash, (i_len >> 8) & 0xff);
735 CryptHashChar(hHash, (i_len) & 0xff);
737 CryptHashData(hHash, p_pkey->psz_username, (DWORD)i_len, 0);
739 return hash_finish(hHash, &p_pkey->sig);
742 static int hash_from_file(HCRYPTHASH hHash, CString filename, signature_packet_t* p_sig)
744 CAutoFILE pFile = _wfsopen(filename, L"rb", SH_DENYWR);
745 if (!pFile)
746 return -1;
748 char buf[4097] = { 0 };
749 int read = 0;
750 int nlHandling = 0;
751 while ((read = (int)fread(buf, sizeof(char), sizeof(buf) - 1, pFile)) > 0)
753 if (p_sig->type == TEXT_SIGNATURE)
755 buf[read] = '\0';
756 char * psz_string = buf;
757 while (*psz_string)
759 if (nlHandling == 1 && (*psz_string == '\r' || *psz_string == '\n'))
761 CryptHashChar(hHash, '\r');
762 CryptHashChar(hHash, '\n');
763 nlHandling = 2;
765 if (nlHandling == 2 && *psz_string == '\r')
767 psz_string++;
768 nlHandling = 2;
769 if (!*psz_string)
770 break;
773 if ((nlHandling == 2 || nlHandling == 3) && *psz_string == '\n')
775 psz_string++;
776 if (!*psz_string)
777 break;
780 size_t i_len = strcspn(psz_string, "\r\n");
782 if (i_len)
784 CryptHashData(hHash, (BYTE *)psz_string, (DWORD)i_len, 0);
785 psz_string += i_len;
788 nlHandling = 1;
789 if (*psz_string == '\r' || *psz_string == '\n')
791 CryptHashChar(hHash, '\r');
792 CryptHashChar(hHash, '\n');
793 nlHandling = 2;
795 if (*psz_string == '\r')
797 psz_string++;
798 nlHandling = 3;
801 if (*psz_string == '\n')
803 psz_string++;
804 nlHandling = 0;
809 else
810 CryptHashData(hHash, (BYTE *)buf, read, 0);
813 return hash_finish(hHash, p_sig);
816 static int check_hash(HCRYPTHASH hHash, signature_packet_t *p_sig)
818 DWORD hashLen;
819 DWORD hashLenLen = sizeof(DWORD);
820 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &hashLenLen, 0))
821 return -1;
823 auto pHash = std::make_unique<BYTE[]>(hashLen);
824 CryptGetHashParam(hHash, HP_HASHVAL, pHash.get(), &hashLen, 0);
826 if (pHash[0] != p_sig->hash_verification[0] || pHash[1] != p_sig->hash_verification[1])
827 return -1;
829 return 0;
833 * Verify an OpenPGP signature made with some RSA public key
835 static int verify_signature_rsa(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_pkey, signature_packet_t& p_sig)
837 int i_n_len = min(mpi_len(p_pkey.key.sig.rsa.n), sizeof(p_pkey.key.sig.rsa.n) - 2);
838 int i_s_len = min(mpi_len(p_sig.algo_specific.rsa.s), sizeof(p_sig.algo_specific.rsa.s) - 2);
840 if (i_s_len > i_n_len)
841 return -1;
843 RSAKEY rsakey;
844 rsakey.blobheader.bType = PUBLICKEYBLOB; // 0x06
845 rsakey.blobheader.bVersion = CUR_BLOB_VERSION; // 0x02
846 rsakey.blobheader.reserved = 0;
847 rsakey.blobheader.aiKeyAlg = CALG_RSA_KEYX;
848 rsakey.rsapubkey.magic = 0x31415352;// ASCII for RSA1
849 rsakey.rsapubkey.bitlen = i_n_len * 8;
850 rsakey.rsapubkey.pubexp = 65537; // gnupg only uses this
852 memcpy(rsakey.n, p_pkey.key.sig.rsa.n + 2, i_n_len); std::reverse(rsakey.n, rsakey.n + i_n_len);
854 HCRYPTKEY hPubKey;
855 if (CryptImportKey(hCryptProv, (BYTE*)&rsakey, sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + i_n_len, 0, 0, &hPubKey) == 0)
856 return -1;
857 SCOPE_EXIT{ CryptDestroyKey(hPubKey); };
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 auto pSig = std::make_unique<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))
869 return -1;
871 return 0;
875 * Verify an OpenPGP signature made with some DSA public key
877 static int verify_signature_dsa(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_pkey, signature_packet_t& p_sig)
879 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
880 return -1;
882 int i_p_len = min(mpi_len(p_pkey.key.sig.dsa.p), sizeof(p_pkey.key.sig.dsa.p) - 2);
883 int i_q_len = min(mpi_len(p_pkey.key.sig.dsa.q), sizeof(p_pkey.key.sig.dsa.q) - 2);
884 int i_g_len = min(mpi_len(p_pkey.key.sig.dsa.g), sizeof(p_pkey.key.sig.dsa.g) - 2);
885 int i_y_len = min(mpi_len(p_pkey.key.sig.dsa.y), sizeof(p_pkey.key.sig.dsa.y) - 2);
886 int i_r_len = min(mpi_len(p_sig.algo_specific.dsa.r), sizeof(p_sig.algo_specific.dsa.r) - 2);
887 int i_s_len = min(mpi_len(p_sig.algo_specific.dsa.s), sizeof(p_sig.algo_specific.dsa.s) - 2);
889 // CryptoAPI only supports 1024-bit DSA keys and SHA1 signatures
890 if (i_p_len > 128 || i_q_len > 20 && i_g_len > 128 || i_y_len > 128 || i_r_len > 20 || i_s_len > 20)
891 return -1;
893 HCRYPTKEY hPubKey;
894 // based on http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-10/0040.html
895 DSAKEY dsakey = { 0 };
896 dsakey.blobheader.bType = PUBLICKEYBLOB; // 0x06
897 dsakey.blobheader.bVersion = CUR_BLOB_VERSION + 1; // 0x03
898 dsakey.blobheader.reserved = 0;
899 dsakey.blobheader.aiKeyAlg = CALG_DSS_SIGN;
900 dsakey.dsspubkeyver3.magic = 0x33535344; // ASCII of "DSS3";
901 dsakey.dsspubkeyver3.bitlenP = i_p_len * 8; // # of bits in prime modulus
902 dsakey.dsspubkeyver3.bitlenQ = i_q_len * 8; // # of bits in prime q, 0 if not available
903 dsakey.dsspubkeyver3.bitlenJ = 0; // # of bits in (p-1)/q, 0 if not available
904 dsakey.dsspubkeyver3.DSSSeed.counter = 0xFFFFFFFF; // not available
906 memcpy(dsakey.p, p_pkey.key.sig.dsa.p + 2, i_p_len); std::reverse(dsakey.p, dsakey.p + i_p_len);
907 memcpy(dsakey.q, p_pkey.key.sig.dsa.q + 2, i_q_len); std::reverse(dsakey.q, dsakey.q + i_q_len);
908 memcpy(dsakey.g, p_pkey.key.sig.dsa.g + 2, i_g_len); std::reverse(dsakey.g, dsakey.g + i_g_len);
909 memcpy(dsakey.y, p_pkey.key.sig.dsa.y + 2, i_y_len); std::reverse(dsakey.y, dsakey.y + i_y_len);
911 if (CryptImportKey(hCryptProv, (BYTE*)&dsakey, sizeof(dsakey), 0, 0, &hPubKey) == 0)
912 return -1;
914 SCOPE_EXIT { CryptDestroyKey(hPubKey); };
916 unsigned char signature[40] = { 0 };
917 memcpy(signature, p_sig.algo_specific.dsa.r + 2, i_r_len);
918 memcpy(signature + 20, p_sig.algo_specific.dsa.s + 2, i_s_len);
919 std::reverse(signature, signature + i_r_len);
920 std::reverse(signature + 20, signature + 20 + i_s_len);
921 if (!CryptVerifySignature(hHash, signature, sizeof(signature), hPubKey, nullptr, 0))
922 return -1;
924 return 0;
928 * Verify an OpenPGP signature made with some public key
930 int verify_signature(HCRYPTPROV hCryptProv, HCRYPTHASH hHash, public_key_t& p_key, signature_packet_t& sign)
932 if (sign.public_key_algo == PUBLIC_KEY_ALGO_DSA)
933 return verify_signature_dsa(hCryptProv, hHash, p_key, sign);
934 else if (sign.public_key_algo == PUBLIC_KEY_ALGO_RSA)
935 return verify_signature_rsa(hCryptProv, hHash, p_key, sign);
936 else
937 return -1;
940 #ifndef GTEST_INCLUDE_GTEST_GTEST_H_
942 * download a public key (the last one) from TortoiseGit server, and parse it
944 static public_key_t *download_key(const uint8_t *p_longid, const uint8_t *p_signature_issuer, CUpdateDownloader *updateDownloader)
946 ASSERT(updateDownloader);
948 CString url;
949 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]);
951 CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
952 if (updateDownloader->DownloadFile(url, tempfile, false))
953 return nullptr;
955 int size = 65536;
956 auto buffer = std::make_unique<char[]>(size);
957 FILE * pFile = _wfsopen(tempfile, L"rb", SH_DENYWR);
958 if (pFile)
960 SCOPE_EXIT{ fclose(pFile); };
961 int length = 0;
962 if ((length = (int)fread(buffer.get(), sizeof(char), size, pFile)) >= 8)
963 size = length;
964 else
965 return nullptr;
967 else
968 return nullptr;
970 public_key_t *p_pkey = (public_key_t*) malloc(sizeof(public_key_t));
971 if (!p_pkey)
973 DeleteUrlCacheEntry(url);
974 return nullptr;
977 memcpy(p_pkey->longid, p_longid, 8);
979 if (parse_public_key((const uint8_t *)buffer.get(), size, p_pkey, p_signature_issuer))
981 free(p_pkey);
982 return nullptr;
985 return p_pkey;
987 #endif
989 int VerifyIntegrity(const CString &filename, const CString &signatureFilename, CUpdateDownloader *updateDownloader)
991 signature_packet_t p_sig = { 0 };
992 if (LoadSignature(signatureFilename, &p_sig))
993 return -1;
994 SCOPE_EXIT
996 if (p_sig.version == 4)
998 free(p_sig.specific.v4.hashed_data);
999 free(p_sig.specific.v4.unhashed_data);
1003 public_key_t p_pkey = { 0 };
1004 if (parse_public_key(tortoisegit_public_key, sizeof(tortoisegit_public_key), &p_pkey, nullptr))
1005 return -1;
1006 SCOPE_EXIT { free(p_pkey.psz_username); };
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))
1011 return -1;
1012 SCOPE_EXIT { CryptReleaseContext(hCryptProv, 0); };
1014 if (memcmp(p_sig.issuer_longid, p_pkey.longid, 8) != 0)
1016 public_key_t *p_new_pkey = nullptr;
1017 #ifndef GTEST_INCLUDE_GTEST_GTEST_H_
1018 if (updateDownloader)
1019 p_new_pkey = download_key(p_sig.issuer_longid, tortoisegit_public_key_longid, updateDownloader);
1020 #else
1021 UNREFERENCED_PARAMETER(updateDownloader);
1022 #endif
1023 if (!p_new_pkey)
1024 return -1;
1025 SCOPE_EXIT
1027 if (p_new_pkey->sig.version == 4)
1029 p_new_pkey->sig.version = 0;
1030 free(p_new_pkey->sig.specific.v4.hashed_data);
1031 free(p_new_pkey->sig.specific.v4.unhashed_data);
1033 if (p_new_pkey == &p_pkey)
1034 return;
1035 free(p_new_pkey->psz_username);
1036 free(p_new_pkey);
1039 HCRYPTHASH hHash;
1040 if (!CryptCreateHash(hCryptProv, map_digestalgo(p_sig.digest_algo), 0, 0, &hHash))
1041 return -1;
1042 SCOPE_EXIT { CryptDestroyHash(hHash); };
1044 if (hash_from_public_key(hHash, p_new_pkey))
1045 return -1;
1047 if (check_hash(hHash, &p_new_pkey->sig))
1048 return -1;
1050 if (verify_signature(hCryptProv, hHash, p_pkey, p_new_pkey->sig))
1051 return -1;
1053 free(p_pkey.psz_username);
1054 p_pkey = *p_new_pkey;
1057 HCRYPTHASH hHash;
1058 if (!CryptCreateHash(hCryptProv, map_digestalgo(p_sig.digest_algo), 0, 0, &hHash))
1059 return -1;
1060 SCOPE_EXIT{ CryptDestroyHash(hHash); };
1062 if (hash_from_file(hHash, filename, &p_sig))
1063 return -1;
1065 if (check_hash(hHash, &p_sig))
1066 return -1;
1068 if (verify_signature(hCryptProv, hHash, p_pkey, p_sig))
1069 return -1;
1071 return 0;