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.
25 #include "UpdateCrypto.h"
26 #include "FormatMessageWrapper.h"
28 #define NEED_SIGNING_KEY
29 #include "../version.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);
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];
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
)
61 size_t n
= mpi_len(buf
);
75 #define READ_MPI(d, bits) do \
77 size_t n = read_mpi(d, p_buf, i_packet_len - i_read, bits); \
84 static size_t b64_decode_binary_to_buffer(uint8_t *p_dst
, size_t i_dst
, const char *p_src
, size_t srcLen
)
87 if (!Base64Decode(p_src
, (int)srcLen
, p_dst
, &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
;
105 crc
^= (*octets
++) << 16;
106 for (i
= 0; i
< 8; i
++)
113 return crc
& 0xFFFFFFL
;
116 static ALG_ID
map_digestalgo(uint8_t digest_algo
)
120 case DIGEST_ALGO_SHA1
:
122 case DIGEST_ALGO_SHA256
:
124 case DIGEST_ALGO_SHA384
:
126 case DIGEST_ALGO_SHA512
:
133 static DWORD
map_algo(uint8_t digest_algo
)
137 case PUBLIC_KEY_ALGO_DSA
:
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
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 */
153 p_sig
->specific
.v3
.hashed_data_len
= *p_buf
++; i_read
++;
154 if (p_sig
->specific
.v3
.hashed_data_len
!= 5)
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
++;
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 */
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
))
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
)
205 p_sig
->specific
.v4
.hashed_data
= (uint8_t*) malloc(i_hashed_data_len
);
206 if (!p_sig
->specific
.v4
.hashed_data
)
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
)
219 p_sig
->specific
.v4
.unhashed_data
= (uint8_t*) malloc(i_unhashed_data_len
);
220 if (!p_sig
->specific
.v4
.unhashed_data
)
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
;
238 size_t i_subpacket_len
;
243 i_subpacket_len
= *p
++;
249 i_subpacket_len
= ((size_t)(*p
++ - 192)) << 8;
250 i_subpacket_len
+= *p
++ + 192;
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
)
267 memcpy(&p_sig
->issuer_longid
, p
+ 1, 8);
272 if (i_subpacket_len
> i_unhashed_data_len
)
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 */
284 p_sig
->version
= *p_buf
++;
287 switch (p_sig
->version
)
290 i_read
= parse_signature_v3_packet(p_sig
, p_buf
, i_packet_len
);
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
);
301 if (i_read
== 0) /* signature packet parsing has failed */
304 if (!map_algo(p_sig
->public_key_algo
))
307 if (!map_digestalgo(p_sig
->digest_algo
))
312 case BINARY_SIGNATURE
:
314 case GENERIC_KEY_SIGNATURE
:
315 case PERSONA_KEY_SIGNATURE
:
316 case CASUAL_KEY_SIGNATURE
:
317 case POSITIVE_KEY_SIGNATURE
:
323 p_buf
--; /* rewind to the version byte */
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);
336 if (i_read
!= i_packet_len
)
342 if (p_sig
->version
== 4)
344 free(p_sig
->specific
.v4
.hashed_data
);
345 free(p_sig
->specific
.v4
.unhashed_data
);
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
;
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')
370 size_t i_line_len
= strcspn(p_ipos
, "\r\n");
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;
383 if (!strncmp(p_ipos
, "Version:", 8))
385 p_ipos
+= i_line_len
+ 1;
389 if (p_ipos
[i_line_len
- 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'))
401 /* XXX: the CRC is OPTIONAL, really require it ? */
402 if (p_ipos
+ 5 > p_ibuf
+ i_ibuf_len
|| *p_ipos
++ != '=')
406 if (b64_decode_binary_to_buffer(p_crc
, sizeof(p_crc
), p_ipos
, 5) != 3)
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)
426 p_key
->version
= *p_buf
++; i_read
++;
427 if (p_key
->version
!= 4)
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
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);
451 if (i_read
== i_packet_len
)
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
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
;
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;
481 { /* first byte is ASCII, unarmoring */
482 p_key_unarmored
= (uint8_t*)malloc(i_key_len
);
483 if (!p_key_unarmored
)
485 int i_len
= pgp_unarmor((char*)p_key_data
, i_key_len
, p_key_unarmored
, i_key_len
);
490 pos
= p_key_unarmored
;
491 max_pos
= pos
+ i_len
;
494 while (pos
< max_pos
)
496 if (!(*pos
& 0x80) || *pos
& 0x40)
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))
505 int i_packet_len
= scalar_number(pos
, i_header_len
);
508 if (pos
+ i_packet_len
> max_pos
|| i_packet_len
< 0 || (size_t)i_packet_len
> i_key_len
)
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)
519 case SIGNATURE_PACKET
: /* we accept only v4 signatures here */
520 if (i_status
& SIGNATURE_FOUND
|| !p_sig_issuer
)
522 if (parse_signature_packet(&p_key
->sig
, pos
, i_packet_len
) == 0)
524 if (p_key
->sig
.version
!= 4)
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;
534 i_status
|= SIGNATURE_FOUND
;
539 if (p_key
->psz_username
) /* save only the first User ID */
541 i_status
|= USER_ID_FOUND
;
542 p_key
->psz_username
= (uint8_t*)malloc(i_packet_len
+ 1);
543 if (!p_key
->psz_username
)
546 memcpy(p_key
->psz_username
, pos
, i_packet_len
);
547 p_key
->psz_username
[i_packet_len
] = '\0';
555 free(p_key_unarmored
);
557 if (!(i_status
& (PUBLIC_KEY_FOUND
| USER_ID_FOUND
)))
560 if (p_sig_issuer
&& !(i_status
& SIGNATURE_FOUND
))
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
);
576 static int LoadSignature(const CString
&signatureFilename
, signature_packet_t
*p_sig
)
578 FILE* pFile
= _wfsopen(signatureFilename
, L
"rb", SH_DENYWR
);
583 auto buffer
= std::make_unique
<unsigned char[]>(size
);
584 int length
= (int)fread(buffer
.get(), sizeof(char), size
, pFile
);
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
);
598 buffer
.swap(unpacked
);
603 if (packet_type(buffer
[0]) != SIGNATURE_PACKET
)
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
)
610 DWORD i_len
= scalar_number((uint8_t *)(buffer
.get() + 1), i_header_len
);
611 if (i_len
+ i_header_len
+ 1 != (DWORD
)size
)
614 if (parse_signature_packet(p_sig
, (uint8_t *)(buffer
.get() + 1 + i_header_len
), i_len
))
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
);
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);
664 { /* RFC 4880 only tells about versions 3 and 4 */
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)
680 if (p_pkey
->sig
.type
< GENERIC_KEY_SIGNATURE
|| p_pkey
->sig
.type
> POSITIVE_KEY_SIGNATURE
)
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
;
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
);
748 char buf
[4097] = { 0 };
751 while ((read
= (int)fread(buf
, sizeof(char), sizeof(buf
) - 1, pFile
)) > 0)
753 if (p_sig
->type
== TEXT_SIGNATURE
)
756 char * psz_string
= buf
;
759 if (nlHandling
== 1 && (*psz_string
== '\r' || *psz_string
== '\n'))
761 CryptHashChar(hHash
, '\r');
762 CryptHashChar(hHash
, '\n');
765 if (nlHandling
== 2 && *psz_string
== '\r')
773 if ((nlHandling
== 2 || nlHandling
== 3) && *psz_string
== '\n')
780 size_t i_len
= strcspn(psz_string
, "\r\n");
784 CryptHashData(hHash
, (BYTE
*)psz_string
, (DWORD
)i_len
, 0);
789 if (*psz_string
== '\r' || *psz_string
== '\n')
791 CryptHashChar(hHash
, '\r');
792 CryptHashChar(hHash
, '\n');
795 if (*psz_string
== '\r')
801 if (*psz_string
== '\n')
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
)
819 DWORD hashLenLen
= sizeof(DWORD
);
820 if (!CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashLen
, &hashLenLen
, 0))
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])
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
)
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
);
855 if (CryptImportKey(hCryptProv
, (BYTE
*)&rsakey
, sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + i_n_len
, 0, 0, &hPubKey
) == 0)
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))
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
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)
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)
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))
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
);
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
);
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))
956 auto buffer
= std::make_unique
<char[]>(size
);
957 FILE * pFile
= _wfsopen(tempfile
, L
"rb", SH_DENYWR
);
960 SCOPE_EXIT
{ fclose(pFile
); };
962 if ((length
= (int)fread(buffer
.get(), sizeof(char), size
, pFile
)) >= 8)
970 public_key_t
*p_pkey
= (public_key_t
*) malloc(sizeof(public_key_t
));
973 DeleteUrlCacheEntry(url
);
977 memcpy(p_pkey
->longid
, p_longid
, 8);
979 if (parse_public_key((const uint8_t *)buffer
.get(), size
, p_pkey
, p_signature_issuer
))
989 int VerifyIntegrity(const CString
&filename
, const CString
&signatureFilename
, CUpdateDownloader
*updateDownloader
)
991 signature_packet_t p_sig
= { 0 };
992 if (LoadSignature(signatureFilename
, &p_sig
))
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))
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
))
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
);
1021 UNREFERENCED_PARAMETER(updateDownloader
);
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
)
1035 free(p_new_pkey
->psz_username
);
1040 if (!CryptCreateHash(hCryptProv
, map_digestalgo(p_sig
.digest_algo
), 0, 0, &hHash
))
1042 SCOPE_EXIT
{ CryptDestroyHash(hHash
); };
1044 if (hash_from_public_key(hHash
, p_new_pkey
))
1047 if (check_hash(hHash
, &p_new_pkey
->sig
))
1050 if (verify_signature(hCryptProv
, hHash
, p_pkey
, p_new_pkey
->sig
))
1053 free(p_pkey
.psz_username
);
1054 p_pkey
= *p_new_pkey
;
1058 if (!CryptCreateHash(hCryptProv
, map_digestalgo(p_sig
.digest_algo
), 0, 0, &hHash
))
1060 SCOPE_EXIT
{ CryptDestroyHash(hHash
); };
1062 if (hash_from_file(hHash
, filename
, &p_sig
))
1065 if (check_hash(hHash
, &p_sig
))
1068 if (verify_signature(hCryptProv
, hHash
, p_pkey
, p_sig
))