1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2013 Sven Strickroth <email@cs-ware.de>
4 // Copyright (C) VLC project (http://videolan.org)
5 // - pgp parsing code was copied from src/misc/update(_crypto)?.c
6 // Copyright (C) The Internet Society (1998). All Rights Reserved.
7 // - crc_octets() was lamely copied from rfc 2440
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software Foundation,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "UpdateCrypto.h"
25 #include "FormatMessageWrapper.h"
27 #define NEED_SIGNING_KEY
28 #include "..\version.h"
31 #define packet_type(c) ((c & 0x3c) >> 2) /* 0x3C = 00111100 */
32 #define packet_header_len(c) ((c & 0x03) + 1) /* number of bytes in a packet header */
34 /* number of data bytes in a MPI */
35 #define mpi_len(mpi) ((scalar_number(mpi, 2) + 7) / 8)
37 #define READ_MPI(n, bits) do { \
38 if (i_read + 2 > i_packet_len) \
40 int len = mpi_len(p_buf); \
41 if (len > (bits) / 8 || i_read + 2 + len > i_packet_len) \
44 memcpy(n, p_buf, len); \
45 p_buf += len; i_read += len; \
48 static inline int scalar_number(const uint8_t *p
, int header_len
)
50 ASSERT(header_len
== 1 || header_len
== 2 || header_len
== 4);
54 else if (header_len
== 2)
55 return (p
[0] << 8) + p
[1];
56 else if (header_len
== 4)
57 return (p
[0] << 24) + (p
[1] << 16) + (p
[2] << 8) + p
[3];
63 static size_t b64_decode_binary_to_buffer(uint8_t *p_dst
, size_t i_dst
, const char *p_src
, size_t srcLen
)
66 if (!Base64Decode(p_src
, (int)srcLen
, p_dst
, &len
))
72 * crc_octets() was lamely copied from rfc 2440
73 * Copyright (C) The Internet Society (1998). All Rights Reserved.
75 #define CRC24_INIT 0xB704CEL
76 #define CRC24_POLY 0x1864CFBL
78 static long crc_octets(uint8_t *octets
, size_t len
)
80 long crc
= CRC24_INIT
;
84 crc
^= (*octets
++) << 16;
85 for (i
= 0; i
< 8; i
++)
92 return crc
& 0xFFFFFFL
;
95 static size_t parse_signature_v3_packet(signature_packet_t
*p_sig
, const uint8_t *p_buf
, size_t i_sig_len
)
97 size_t i_read
= 1; /* we already read the version byte */
99 if (i_sig_len
< 19) /* signature is at least 19 bytes + the 2 MPIs */
102 p_sig
->specific
.v3
.hashed_data_len
= *p_buf
++; i_read
++;
103 if (p_sig
->specific
.v3
.hashed_data_len
!= 5)
106 p_sig
->type
= *p_buf
++; i_read
++;
108 memcpy(p_sig
->specific
.v3
.timestamp
, p_buf
, 4);
109 p_buf
+= 4; i_read
+= 4;
111 memcpy(p_sig
->issuer_longid
, p_buf
, 8);
112 p_buf
+= 8; i_read
+= 8;
114 p_sig
->public_key_algo
= *p_buf
++; i_read
++;
116 p_sig
->digest_algo
= *p_buf
++; i_read
++;
118 p_sig
->hash_verification
[0] = *p_buf
++; i_read
++;
119 p_sig
->hash_verification
[1] = *p_buf
++; i_read
++;
121 ASSERT(i_read
== 19);
127 * fill a signature_packet_v4_t from signature packet data
128 * verify that it was used with a DSA public key, using SHA-1 digest
130 static size_t parse_signature_v4_packet(signature_packet_t
*p_sig
, const uint8_t *p_buf
, size_t i_sig_len
)
132 size_t i_read
= 1; /* we already read the version byte */
134 if (i_sig_len
< 10) /* signature is at least 10 bytes + the 2 MPIs */
137 p_sig
->type
= *p_buf
++; i_read
++;
139 p_sig
->public_key_algo
= *p_buf
++; i_read
++;
141 p_sig
->digest_algo
= *p_buf
++; i_read
++;
143 memcpy(p_sig
->specific
.v4
.hashed_data_len
, p_buf
, 2);
144 p_buf
+= 2; i_read
+= 2;
146 size_t i_hashed_data_len
= scalar_number(p_sig
->specific
.v4
.hashed_data_len
, 2);
147 i_read
+= i_hashed_data_len
;
148 if (i_read
+ 4 > i_sig_len
)
151 p_sig
->specific
.v4
.hashed_data
= (uint8_t*) malloc(i_hashed_data_len
);
152 if (!p_sig
->specific
.v4
.hashed_data
)
154 memcpy(p_sig
->specific
.v4
.hashed_data
, p_buf
, i_hashed_data_len
);
155 p_buf
+= i_hashed_data_len
;
157 memcpy(p_sig
->specific
.v4
.unhashed_data_len
, p_buf
, 2);
158 p_buf
+= 2; i_read
+= 2;
160 size_t i_unhashed_data_len
= scalar_number(p_sig
->specific
.v4
.unhashed_data_len
, 2);
161 i_read
+= i_unhashed_data_len
;
162 if (i_read
+ 2 > i_sig_len
)
165 p_sig
->specific
.v4
.unhashed_data
= (uint8_t*) malloc(i_unhashed_data_len
);
166 if (!p_sig
->specific
.v4
.unhashed_data
)
169 memcpy(p_sig
->specific
.v4
.unhashed_data
, p_buf
, i_unhashed_data_len
);
170 p_buf
+= i_unhashed_data_len
;
172 memcpy(p_sig
->hash_verification
, p_buf
, 2);
173 p_buf
+= 2; i_read
+= 2;
175 uint8_t *p
, *max_pos
;
176 p
= p_sig
->specific
.v4
.unhashed_data
;
177 max_pos
= p
+ scalar_number(p_sig
->specific
.v4
.unhashed_data_len
, 2);
184 size_t i_subpacket_len
;
189 i_subpacket_len
= *p
++;
195 i_subpacket_len
= (*p
++ - 192) << 8;
196 i_subpacket_len
+= *p
++ + 192;
202 i_subpacket_len
= *++p
<< 24;
203 i_subpacket_len
+= *++p
<< 16;
204 i_subpacket_len
+= *++p
<< 8;
205 i_subpacket_len
+= *++p
;
208 if (*p
== ISSUER_SUBPACKET
)
213 memcpy(&p_sig
->issuer_longid
, p
+ 1, 8);
218 p
+= i_subpacket_len
;
222 static int parse_signature_packet(signature_packet_t
*p_sig
, const uint8_t *p_buf
, size_t i_packet_len
)
224 if (!i_packet_len
) /* 1st sanity check, we need at least the version */
227 p_sig
->version
= *p_buf
++;
230 switch (p_sig
->version
)
233 i_read
= parse_signature_v3_packet(p_sig
, p_buf
, i_packet_len
);
236 p_sig
->specific
.v4
.hashed_data
= nullptr;
237 p_sig
->specific
.v4
.unhashed_data
= nullptr;
238 i_read
= parse_signature_v4_packet(p_sig
, p_buf
, i_packet_len
);
244 if (i_read
== 0) /* signature packet parsing has failed */
247 if (p_sig
->public_key_algo
!= PUBLIC_KEY_ALGO_DSA
)
250 if (p_sig
->digest_algo
!= DIGEST_ALGO_SHA1
)
255 case BINARY_SIGNATURE
:
257 case GENERIC_KEY_SIGNATURE
:
258 case PERSONA_KEY_SIGNATURE
:
259 case CASUAL_KEY_SIGNATURE
:
260 case POSITIVE_KEY_SIGNATURE
:
266 p_buf
--; /* rewind to the version byte */
269 READ_MPI(p_sig
->r
, 160);
270 READ_MPI(p_sig
->s
, 160);
272 ASSERT(i_read
== i_packet_len
);
273 if (i_read
< i_packet_len
) /* some extra data, hm ? */
279 if (p_sig
->version
== 4)
281 free(p_sig
->specific
.v4
.hashed_data
);
282 free(p_sig
->specific
.v4
.unhashed_data
);
289 * Transform an armored document in binary format
290 * Used on public keys and signatures
292 static int pgp_unarmor(const char *p_ibuf
, size_t i_ibuf_len
, uint8_t *p_obuf
, size_t i_obuf_len
)
294 const char *p_ipos
= p_ibuf
;
295 uint8_t *p_opos
= p_obuf
;
297 int i_header_skipped
= 0;
299 while (!i_end
&& p_ipos
< p_ibuf
+ i_ibuf_len
&& *p_ipos
!= '=')
301 if (*p_ipos
== '\r' || *p_ipos
== '\n')
307 size_t i_line_len
= strcspn(p_ipos
, "\r\n");
311 if (!i_header_skipped
)
313 if (!strncmp(p_ipos
, "-----BEGIN PGP", 14))
314 i_header_skipped
= 1;
316 p_ipos
+= i_line_len
+ 1;
320 if (!strncmp(p_ipos
, "Version:", 8))
322 p_ipos
+= i_line_len
+ 1;
326 if (p_ipos
[i_line_len
- 1] == '=')
331 p_opos
+= b64_decode_binary_to_buffer(p_opos
, p_obuf
- p_opos
+ i_obuf_len
, p_ipos
, (int)i_line_len
);
332 p_ipos
+= i_line_len
+ 1;
335 if (p_ipos
+ 1 < p_ibuf
+ i_ibuf_len
&& (*p_ipos
== '\r' || *p_ipos
== '\n'))
338 /* XXX: the CRC is OPTIONAL, really require it ? */
339 if (p_ipos
+ 5 > p_ibuf
+ i_ibuf_len
|| *p_ipos
++ != '=')
343 if (b64_decode_binary_to_buffer(p_crc
, sizeof(p_crc
), p_ipos
, 5) != 3)
346 long l_crc
= crc_octets(p_obuf
, p_opos
- p_obuf
);
347 long l_crc2
= (0 << 24) + (p_crc
[0] << 16) + (p_crc
[1] << 8) + p_crc
[2];
349 return (int)((l_crc2
== l_crc
) ? p_opos
- p_obuf
: 0);
353 * fill a public_key_packet_t structure from public key packet data
354 * verify that it is a version 4 public key packet, using DSA
356 static int parse_public_key_packet(public_key_packet_t
*p_key
, const uint8_t *p_buf
, size_t i_packet_len
)
358 if (i_packet_len
> 418 || i_packet_len
< 6)
363 p_key
->version
= *p_buf
++; i_read
++;
364 if (p_key
->version
!= 4)
367 /* XXX: warn when timestamp is > date ? */
368 memcpy(p_key
->timestamp
, p_buf
, 4); p_buf
+= 4; i_read
+= 4;
370 p_key
->algo
= *p_buf
++; i_read
++;
371 if (p_key
->algo
!= PUBLIC_KEY_ALGO_DSA
)
374 READ_MPI(p_key
->p
, 1024);
375 READ_MPI(p_key
->q
, 160);
376 READ_MPI(p_key
->g
, 1024);
377 READ_MPI(p_key
->y
, 1024);
379 if (i_read
!= i_packet_len
) /* some extra data eh ? */
389 * fill a public_key_t with public key data, including:
390 * * public key packet
391 * * signature packet issued by key which long id is p_sig_issuer
394 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
)
396 const uint8_t *pos
= p_key_data
;
397 const uint8_t *max_pos
= pos
+ i_key_len
;
400 #define PUBLIC_KEY_FOUND 0x01
401 #define USER_ID_FOUND 0x02
402 #define SIGNATURE_FOUND 0X04
404 uint8_t *p_key_unarmored
= nullptr;
406 p_key
->psz_username
= nullptr;
407 p_key
->sig
.specific
.v4
.hashed_data
= nullptr;
408 p_key
->sig
.specific
.v4
.unhashed_data
= nullptr;
411 { /* first byte is ASCII, unarmoring */
412 p_key_unarmored
= (uint8_t*)malloc(i_key_len
);
413 if (!p_key_unarmored
)
415 int i_len
= pgp_unarmor((char*)p_key_data
, i_key_len
, p_key_unarmored
, i_key_len
);
420 pos
= p_key_unarmored
;
421 max_pos
= pos
+ i_len
;
424 while (pos
< max_pos
)
426 if (!(*pos
& 0x80) || *pos
& 0x40)
429 int i_type
= packet_type(*pos
);
431 int i_header_len
= packet_header_len(*pos
++);
432 if (pos
+ i_header_len
> max_pos
|| (i_header_len
!= 1 && i_header_len
!= 2 && i_header_len
!= 4))
435 int i_packet_len
= scalar_number(pos
, i_header_len
);
438 if (pos
+ i_packet_len
> max_pos
)
443 case PUBLIC_KEY_PACKET
:
444 i_status
|= PUBLIC_KEY_FOUND
;
445 if (parse_public_key_packet(&p_key
->key
, pos
, i_packet_len
) != 0)
449 case SIGNATURE_PACKET
: /* we accept only v4 signatures here */
450 if (i_status
& SIGNATURE_FOUND
|| !p_sig_issuer
)
452 if (parse_signature_packet(&p_key
->sig
, pos
, i_packet_len
) == 0)
454 if (p_key
->sig
.version
!= 4)
456 if (memcmp( p_key
->sig
.issuer_longid
, p_sig_issuer
, 8))
458 free(p_key
->sig
.specific
.v4
.hashed_data
);
459 free(p_key
->sig
.specific
.v4
.unhashed_data
);
460 p_key
->sig
.specific
.v4
.hashed_data
= nullptr;
461 p_key
->sig
.specific
.v4
.unhashed_data
= nullptr;
464 i_status
|= SIGNATURE_FOUND
;
469 if (p_key
->psz_username
) /* save only the first User ID */
471 i_status
|= USER_ID_FOUND
;
472 p_key
->psz_username
= (uint8_t*)malloc(i_packet_len
+ 1);
473 if (!p_key
->psz_username
)
476 memcpy(p_key
->psz_username
, pos
, i_packet_len
);
477 p_key
->psz_username
[i_packet_len
] = '\0';
485 free(p_key_unarmored
);
487 if (!(i_status
& (PUBLIC_KEY_FOUND
| USER_ID_FOUND
)))
490 if (p_sig_issuer
&& !(i_status
& SIGNATURE_FOUND
))
496 if (p_key
->sig
.version
== 4)
498 free(p_key
->sig
.specific
.v4
.hashed_data
);
499 free(p_key
->sig
.specific
.v4
.unhashed_data
);
501 free(p_key
->psz_username
);
502 free(p_key_unarmored
);
506 static int LoadSignature(const CString
&signatureFilename
, signature_packet_t
*p_sig
)
508 FILE * pFile
= _tfsopen(signatureFilename
, _T("rb"), SH_DENYWR
);
512 std::unique_ptr
<unsigned char[]> buffer(new unsigned char[size
]);
514 if ((length
= (int)fread(buffer
.get(), sizeof(char), size
, pFile
)) >= 8)
517 // is unpacking needed?
518 if ((uint8_t)buffer
[0] < 0x80)
520 std::unique_ptr
<unsigned char[]> unpacked(new unsigned char[size
]);
521 size
= pgp_unarmor((char *)buffer
.get(), length
, unpacked
.get(), length
);
526 buffer
.swap(unpacked
);
531 if (packet_type(buffer
[0]) != SIGNATURE_PACKET
)
534 DWORD i_header_len
= packet_header_len(buffer
[0]);
535 if ((i_header_len
!= 1 && i_header_len
!= 2 && i_header_len
!= 4) || i_header_len
+ 1 > (DWORD
)size
)
538 DWORD i_len
= scalar_number((uint8_t *)(buffer
.get() + 1), i_header_len
);
539 if (i_len
+ i_header_len
+ 1 != (DWORD
)size
)
542 if (parse_signature_packet(p_sig
, (uint8_t *)(buffer
.get() + 1 + i_header_len
), i_len
))
545 if (p_sig
->type
!= BINARY_SIGNATURE
&& p_sig
->type
!= TEXT_SIGNATURE
)
547 if (p_sig
->version
== 4)
549 free(p_sig
->specific
.v4
.hashed_data
);
550 free(p_sig
->specific
.v4
.unhashed_data
);
563 static void CryptHashChar(HCRYPTHASH hHash
, const int c
)
565 CryptHashData(hHash
, (BYTE
*)&c
, 1, 0);
568 /* final part of the hash */
569 static int hash_finish(HCRYPTHASH hHash
, signature_packet_t
*p_sig
)
571 if (p_sig
->version
== 3)
573 CryptHashChar(hHash
, p_sig
->type
);
574 CryptHashData(hHash
, (unsigned char*)&p_sig
->specific
.v3
.timestamp
, 4, 0);
576 else if (p_sig
->version
== 4)
578 CryptHashChar(hHash
, p_sig
->version
);
579 CryptHashChar(hHash
, p_sig
->type
);
580 CryptHashChar(hHash
, p_sig
->public_key_algo
);
581 CryptHashChar(hHash
, p_sig
->digest_algo
);
582 CryptHashData(hHash
, p_sig
->specific
.v4
.hashed_data_len
, 2, 0);
583 unsigned int i_len
= scalar_number(p_sig
->specific
.v4
.hashed_data_len
, 2);
584 CryptHashData(hHash
, p_sig
->specific
.v4
.hashed_data
, i_len
, 0);
586 CryptHashChar(hHash
, 0x04);
587 CryptHashChar(hHash
, 0xFF);
589 i_len
+= 6; /* hashed data + 6 bytes header */
591 CryptHashChar(hHash
, (i_len
>> 24) & 0xff);
592 CryptHashChar(hHash
, (i_len
>> 16) & 0xff);
593 CryptHashChar(hHash
, (i_len
>> 8) & 0xff);
594 CryptHashChar(hHash
, (i_len
) & 0xff);
597 { /* RFC 4880 only tells about versions 3 and 4 */
605 * Generate a SHA1 hash on a public key, to verify a signature made on that hash
606 * Note that we need the signature (v4) to compute the hash
608 static int hash_sha1_from_public_key(HCRYPTHASH hHash
, public_key_t
*p_pkey
)
610 if (p_pkey
->sig
.version
!= 4)
613 if (p_pkey
->sig
.type
< GENERIC_KEY_SIGNATURE
|| p_pkey
->sig
.type
> POSITIVE_KEY_SIGNATURE
)
616 CryptHashChar(hHash
, 0x99);
618 unsigned int i_p_len
= mpi_len(p_pkey
->key
.p
);
619 unsigned int i_g_len
= mpi_len(p_pkey
->key
.g
);
620 unsigned int i_q_len
= mpi_len(p_pkey
->key
.q
);
621 unsigned int i_y_len
= mpi_len(p_pkey
->key
.y
);
623 DWORD i_size
= 6 + 2*4 + i_p_len
+ i_g_len
+ i_q_len
+ i_y_len
;
625 CryptHashChar(hHash
, (i_size
>> 8) & 0xff);
626 CryptHashChar(hHash
, i_size
& 0xff);
628 CryptHashChar(hHash
, p_pkey
->key
.version
);
629 CryptHashData(hHash
, p_pkey
->key
.timestamp
, 4, 0);
630 CryptHashChar(hHash
, p_pkey
->key
.algo
);
632 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.p
, 2, 0);
633 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.p
+ 2, i_p_len
, 0);
635 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.q
, 2, 0);
636 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.q
+ 2, i_q_len
, 0);
638 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.g
, 2, 0);
639 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.g
+ 2, i_g_len
, 0);
641 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.y
, 2, 0);
642 CryptHashData(hHash
, (uint8_t*)&p_pkey
->key
.y
+ 2, i_y_len
, 0);
644 CryptHashChar(hHash
, 0xb4);
646 size_t i_len
= strlen((char *)p_pkey
->psz_username
);
648 CryptHashChar(hHash
, (i_len
>> 24) & 0xff);
649 CryptHashChar(hHash
, (i_len
>> 16) & 0xff);
650 CryptHashChar(hHash
, (i_len
>> 8) & 0xff);
651 CryptHashChar(hHash
, (i_len
) & 0xff);
653 CryptHashData(hHash
, p_pkey
->psz_username
, (DWORD
)i_len
, 0);
655 return hash_finish(hHash
, &p_pkey
->sig
);
658 static int hash_sha1_from_file(HCRYPTHASH hHash
, CString filename
, signature_packet_t
*p_sig
)
660 FILE * pFile
= _tfsopen(filename
, _T("rb"), SH_DENYWR
);
667 while ((read
= (int)fread(buf
, sizeof(char), sizeof(buf
) - 1, pFile
)) > 0)
669 if (p_sig
->type
== TEXT_SIGNATURE
)
672 char * psz_string
= buf
;
675 if (nlHandling
== 1 && (*psz_string
== '\r' || *psz_string
== '\n'))
677 CryptHashChar(hHash
, '\r');
678 CryptHashChar(hHash
, '\n');
681 if (nlHandling
== 2 && *psz_string
== '\r')
689 if ((nlHandling
== 2 || nlHandling
== 3) && *psz_string
== '\n')
696 size_t i_len
= strcspn(psz_string
, "\r\n");
700 CryptHashData(hHash
, (BYTE
*)psz_string
, (DWORD
)i_len
, 0);
705 if (*psz_string
== '\r' || *psz_string
== '\n')
707 CryptHashChar(hHash
, '\r');
708 CryptHashChar(hHash
, '\n');
711 if (*psz_string
== '\r')
717 if (*psz_string
== '\n')
726 CryptHashData(hHash
, (BYTE
*)buf
, read
, 0);
731 return hash_finish(hHash
, p_sig
);
734 static int check_hash(HCRYPTHASH hHash
, signature_packet_t
*p_sig
)
737 unsigned char hash
[20];
738 CryptGetHashParam(hHash
, HP_HASHVAL
, hash
, &len
, 0);
740 if (hash
[0] != p_sig
->hash_verification
[0] || hash
[1] != p_sig
->hash_verification
[1])
746 static int verify_signature(HCRYPTPROV hCryptProv
, HCRYPTHASH hHash
, public_key_t
&p_pkey
, signature_packet_t
&p_sig
)
749 // based on http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-10/0040.html
751 dsakey
.blobheader
.bType
= PUBLICKEYBLOB
; // 0x06
752 dsakey
.blobheader
.bVersion
= CUR_BLOB_VERSION
+ 1; // 0x03
753 dsakey
.blobheader
.reserved
= 0;
754 dsakey
.blobheader
.aiKeyAlg
= CALG_DSS_SIGN
;
755 dsakey
.dsspubkeyver3
.magic
= 0x33535344; // ASCII of "DSS3";
756 dsakey
.dsspubkeyver3
.bitlenP
= 1024; // # of bits in prime modulus
757 dsakey
.dsspubkeyver3
.bitlenQ
= 160; // # of bits in prime q, 0 if not available
758 dsakey
.dsspubkeyver3
.bitlenJ
= 0; // # of bits in (p-1)/q, 0 if not available
759 dsakey
.dsspubkeyver3
.DSSSeed
.counter
= 0xFFFFFFFF; // not available
761 memcpy(dsakey
.p
, p_pkey
.key
.p
+ 2, sizeof(p_pkey
.key
.p
) - 2); std::reverse(dsakey
.p
, dsakey
.p
+ sizeof(dsakey
.p
));
762 memcpy(dsakey
.q
, p_pkey
.key
.q
+ 2, sizeof(p_pkey
.key
.q
) - 2); std::reverse(dsakey
.q
, dsakey
.q
+ sizeof(dsakey
.q
));
763 memcpy(dsakey
.g
, p_pkey
.key
.g
+ 2, sizeof(p_pkey
.key
.g
) - 2); std::reverse(dsakey
.g
, dsakey
.g
+ sizeof(dsakey
.g
));
764 memcpy(dsakey
.y
, p_pkey
.key
.y
+ 2, sizeof(p_pkey
.key
.y
) - 2); std::reverse(dsakey
.y
, dsakey
.y
+ sizeof(dsakey
.y
));
766 if (CryptImportKey(hCryptProv
, (BYTE
*)&dsakey
, sizeof(dsakey
), 0, 0, &hPubKey
) == 0)
769 unsigned char signature
[40];
770 memcpy(signature
, p_sig
.r
+ 2, 20);
771 memcpy(signature
+ 20, p_sig
.s
+ 2, 20);
772 std::reverse(signature
, signature
+ 20);
773 std::reverse(signature
+ 20, signature
+ 40);
774 if (!CryptVerifySignature(hHash
, signature
, sizeof(signature
), hPubKey
, nullptr, 0))
776 CryptDestroyKey(hPubKey
);
780 CryptDestroyKey(hPubKey
);
785 * download a public key (the last one) from TortoiseGit server, and parse it
787 static public_key_t
*download_key(const uint8_t *p_longid
, const uint8_t *p_signature_issuer
)
790 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]);
792 CString tempfile
= CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();
793 if (URLDownloadToFile(nullptr, url
, tempfile
, 0, nullptr) != S_OK
)
797 std::unique_ptr
<char[]> buffer(new char[size
]);
798 FILE * pFile
= _tfsopen(tempfile
, _T("rb"), SH_DENYWR
);
802 if ((length
= (int)fread(buffer
.get(), sizeof(char), size
, pFile
)) >= 8)
816 public_key_t
*p_pkey
= (public_key_t
*) malloc(sizeof(public_key_t
));
819 DeleteUrlCacheEntry(url
);
823 memcpy(p_pkey
->longid
, p_longid
, 8);
825 if (parse_public_key((const uint8_t *)buffer
.get(), size
, p_pkey
, p_signature_issuer
))
834 int VerifyIntegrity(const CString
&filename
, const CString
&signatureFilename
)
836 signature_packet_t p_sig
;
837 memset(&p_sig
, 0, sizeof(signature_packet_t
));
838 if (LoadSignature(signatureFilename
, &p_sig
))
842 memset(&p_pkey
, 0, sizeof(public_key_t
));
843 if (parse_public_key(tortoisegit_public_key
, sizeof(tortoisegit_public_key
), &p_pkey
, nullptr))
845 if (p_sig
.version
== 4)
847 free(p_sig
.specific
.v4
.hashed_data
);
848 free(p_sig
.specific
.v4
.unhashed_data
);
852 memcpy(p_pkey
.longid
, tortoisegit_public_key_longid
, 8);
854 HCRYPTPROV hCryptProv
;
855 if (!CryptAcquireContext(&hCryptProv
, nullptr, nullptr, PROV_DSS
, CRYPT_VERIFYCONTEXT
))
857 if (p_sig
.version
== 4)
859 free(p_sig
.specific
.v4
.hashed_data
);
860 free(p_sig
.specific
.v4
.unhashed_data
);
862 free(p_pkey
.psz_username
);
866 if (memcmp(p_sig
.issuer_longid
, p_pkey
.longid
, 8) != 0)
868 public_key_t
*p_new_pkey
= download_key(p_sig
.issuer_longid
, tortoisegit_public_key_longid
);
871 if (p_sig
.version
== 4)
873 free(p_sig
.specific
.v4
.hashed_data
);
874 free(p_sig
.specific
.v4
.unhashed_data
);
876 free(p_pkey
.psz_username
);
877 CryptReleaseContext(hCryptProv
, 0);
882 if (!CryptCreateHash(hCryptProv
, CALG_SHA1
, 0, 0, &hHash
))
884 if (p_sig
.version
== 4)
886 free(p_sig
.specific
.v4
.hashed_data
);
887 free(p_sig
.specific
.v4
.unhashed_data
);
889 free(p_pkey
.psz_username
);
890 CryptReleaseContext(hCryptProv
, 0);
891 free(p_new_pkey
->psz_username
);
892 if (p_new_pkey
->sig
.version
== 4)
894 free(p_new_pkey
->sig
.specific
.v4
.hashed_data
);
895 free(p_new_pkey
->sig
.specific
.v4
.unhashed_data
);
901 if (hash_sha1_from_public_key(hHash
, p_new_pkey
))
903 if (p_sig
.version
== 4)
905 free(p_sig
.specific
.v4
.hashed_data
);
906 free(p_sig
.specific
.v4
.unhashed_data
);
908 free(p_pkey
.psz_username
);
909 CryptReleaseContext(hCryptProv
, 0);
910 free(p_new_pkey
->psz_username
);
911 if (p_new_pkey
->sig
.version
== 4)
913 free(p_new_pkey
->sig
.specific
.v4
.hashed_data
);
914 free(p_new_pkey
->sig
.specific
.v4
.unhashed_data
);
917 CryptDestroyHash(hHash
);
921 if (check_hash(hHash
, &p_new_pkey
->sig
))
923 if (p_sig
.version
== 4)
925 free(p_sig
.specific
.v4
.hashed_data
);
926 free(p_sig
.specific
.v4
.unhashed_data
);
928 free(p_pkey
.psz_username
);
929 CryptReleaseContext(hCryptProv
, 0);
930 free(p_new_pkey
->psz_username
);
931 if (p_new_pkey
->sig
.version
== 4)
933 free(p_new_pkey
->sig
.specific
.v4
.hashed_data
);
934 free(p_new_pkey
->sig
.specific
.v4
.unhashed_data
);
937 CryptDestroyHash(hHash
);
941 if (verify_signature(hCryptProv
, hHash
, p_pkey
, p_new_pkey
->sig
))
943 if (p_sig
.version
== 4)
945 free(p_sig
.specific
.v4
.hashed_data
);
946 free(p_sig
.specific
.v4
.unhashed_data
);
948 free(p_pkey
.psz_username
);
949 CryptReleaseContext(hCryptProv
, 0);
950 free(p_new_pkey
->psz_username
);
951 if (p_new_pkey
->sig
.version
== 4)
953 free(p_new_pkey
->sig
.specific
.v4
.hashed_data
);
954 free(p_new_pkey
->sig
.specific
.v4
.unhashed_data
);
957 CryptDestroyHash(hHash
);
962 CryptDestroyHash(hHash
);
963 free(p_pkey
.psz_username
);
964 p_pkey
= *p_new_pkey
;
965 if (p_pkey
.sig
.version
== 4)
967 p_pkey
.sig
.version
= 0;
968 free(p_pkey
.sig
.specific
.v4
.hashed_data
);
969 free(p_pkey
.sig
.specific
.v4
.unhashed_data
);
978 if (!CryptCreateHash(hCryptProv
, CALG_SHA1
, 0, 0, &hHash
))
981 if (hash_sha1_from_file(hHash
, filename
, &p_sig
))
984 if (check_hash(hHash
, &p_sig
))
987 if (verify_signature(hCryptProv
, hHash
, p_pkey
, p_sig
))
993 CryptDestroyHash(hHash
);
994 CryptReleaseContext(hCryptProv
, 0);
996 free(p_pkey
.psz_username
);
997 if (p_sig
.version
== 4)
999 free(p_sig
.specific
.v4
.hashed_data
);
1000 free(p_sig
.specific
.v4
.unhashed_data
);