Skip to content

Commit 4f87117

Browse files
committed
use git hashing instead of hashlib
1 parent 888119a commit 4f87117

2 files changed

Lines changed: 49 additions & 16 deletions

File tree

git-incrypt

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import tempfile
2626
import os
2727
import sys
2828
import re
29-
import hashlib
3029
import argparse
3130
import enum
3231
import ctypes
@@ -46,6 +45,9 @@ plugin.encryptrefname.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
4645
plugin.decryptrefname.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
4746
plugin.set_option.argtypes = [ctypes.c_char_p, ctypes.c_size_t,
4847
ctypes.c_char_p]
48+
plugin.hashdata.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
49+
plugin.hashdatahex.argtypes = [ctypes.c_void_p, ctypes.c_size_t]
50+
plugin.hashdatahex.restype = ctypes.c_char_p
4951

5052
if not hasattr(pygit2.enums, 'FileMode'):
5153
class FileMode(enum.IntFlag):
@@ -118,6 +120,19 @@ def decryptrefname(ref, key):
118120
return output.value.decode('utf-8')
119121

120122

123+
def sha1(data):
124+
'sha1 hash of data'
125+
output = ctypes.create_string_buffer(20)
126+
poutput = ctypes.c_void_p(ctypes.addressof(output))
127+
plugin.hashdata(data, len(data), poutput)
128+
return output.raw[:20]
129+
130+
131+
def sha1hex(data):
132+
'sha1 hash of data'
133+
return plugin.hashdatahex(data, len(data)).decode('utf-8')
134+
135+
121136
# pylint: disable=pointless-string-statement
122137
'''
123138
mykey = b'x123456789abcdefy123456789abcdefz123456789abcdef'
@@ -135,7 +150,6 @@ plugin.decryptrefname(('refs/heads/' + encoded).encode('utf-8'), poutput)
135150
print(output.value)
136151
plugin.decryptrefname(encoded.encode('utf-8'), poutput)
137152
print(output.value)
138-
139153
sys.exit(0)
140154
'''
141155

@@ -147,8 +161,7 @@ class CryptRepo:
147161
def __init__(self, clearname, url, init=None, forcetrust=False):
148162
assert clearname, 'This does not work yet outside a git repository'
149163
plugin.globalinit()
150-
hashstr = hashlib.sha1(url.encode('utf-8')).hexdigest()
151-
self.prefix = f'refs/incrypt/{hashstr}/'
164+
self.prefix = f'refs/incrypt/{sha1hex(url.encode("utf-8"))}/'
152165
self.url = url
153166
if init:
154167
self.repo = pygit2.init_repository(clearname, bare=True)
@@ -479,18 +492,18 @@ class MetaData:
479492
self.files['ver'] = self.repo.create_blob(MetaData.VER)
480493
self.key = os.urandom(48)
481494
keyhashbase = MetaData.KEYVER + b'\x00' + self.key
482-
self.keyhash = hashlib.sha1(keyhashbase).hexdigest()
495+
self.keyhash = sha1hex(keyhashbase)
483496
cryptedkey = self._gpg(
484497
['-q', '-e'] + ['-r' + k for k in gpgkeys], keyhashbase)
485498
self.files['key'] = self.repo.create_blob(cryptedkey)
486499
self.files['sig'] = self.repo.TreeBuilder().write()
487500
self.template = template
488501
self.files['msg'] = self.repo.create_blob(encryptdata(
489-
hashlib.sha1(template).digest() + template, self.key))
502+
sha1(template) + template, self.key))
490503
self.defaultbranch = defaultbranch
491504
encodedbranch = defaultbranch.encode('utf-8')
492505
self.files['def'] = self.repo.create_blob(encryptdata(
493-
hashlib.sha1(encodedbranch).digest() + encodedbranch, self.key))
506+
sha1(encodedbranch) + encodedbranch, self.key))
494507
self.write()
495508
return self
496509

@@ -514,7 +527,7 @@ class MetaData:
514527
obj = tree['key']
515528
self.files['key'] = obj.id
516529
data = self._gpg(['-q', '-d'], obj.read_raw())
517-
newkeyhash = hashlib.sha1(data).hexdigest()
530+
newkeyhash = sha1hex(data)
518531
if self.keyhash:
519532
assert newkeyhash == self.keyhash, \
520533
f'Key hash is {newkeyhash}, was {self.keyhash}'
@@ -532,22 +545,21 @@ class MetaData:
532545
obj = tree['msg']
533546
self.files['msg'] = obj.id
534547
data = decryptdata(obj.read_raw(), self.key)
535-
assert hashlib.sha1(data[20:]).digest() == \
536-
data[0:20], 'corrupted template'
548+
assert sha1(data[20:]) == data[0:20], 'corrupted template'
537549
self.template = data[20:]
538550
obj = tree['def']
539551
self.files['def'] = obj.id
540552
data = decryptdata(obj.read_raw(), self.key)
541-
assert hashlib.sha1(data[20:]).digest() == \
542-
data[0:20], 'corrupted default branch information'
553+
assert sha1(data[20:]) == data[0:20], \
554+
'corrupted default branch information'
543555
self.defaultbranch = data[20:].decode('utf-8')
544556
return self
545557

546558
def sign(self):
547559
'sign key'
548560
sig = self._gpg(['-q', '-b', '-s'], self.key)
549561
sigfile = self.repo.create_blob(encryptdata(
550-
hashlib.sha1(sig).digest() + sig, self.key))
562+
sha1(sig) + sig, self.key))
551563
sigtree = self.repo.TreeBuilder(self.repo.get(self.files['sig']))
552564
sigtree.insert(str(sigfile), sigfile, pygit2.enums.FileMode.BLOB)
553565
self.files['sig'] = sigtree.write()
@@ -557,8 +569,8 @@ class MetaData:
557569
trusted = False
558570
for sig in self.repo.get(self.files['sig']):
559571
decrypted = decryptdata(sig.read_raw(), self.key)
560-
assert hashlib.sha1(decrypted[20:]).digest() == \
561-
decrypted[0:20], 'corrupted signature'
572+
assert sha1(decrypted[20:]) == decrypted[0:20], \
573+
'corrupted signature'
562574
with tempfile.NamedTemporaryFile(delete=False) as tmp:
563575
tmp.write(decrypted[20:])
564576
tmp.flush()
@@ -596,7 +608,7 @@ class MetaData:
596608
for a, b in cryptmap.items():
597609
rawdata += bytes.fromhex(a) + bytes.fromhex(b)
598610
mapfile = self.repo.create_blob(encryptdata(
599-
hashlib.sha1(rawdata).digest() + rawdata, self.key))
611+
sha1(rawdata) + rawdata, self.key))
600612
collector.insert('map', mapfile, pygit2.enums.FileMode.BLOB)
601613
readmefile = self.repo.create_blob(CRYPTREADME.encode('utf-8'))
602614
collector.insert('README.md', readmefile, pygit2.enums.FileMode.BLOB)

incrypt-plugin.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
#include <openssl/err.h>
77
#include <openssl/evp.h>
88

9+
//#define USE_THE_REPOSITORY_VARIABLE
10+
911
#include "git-compat-util.h"
1012
#include "hash.h"
13+
#include "hex.h"
1114

1215
void globalinit(void);
1316
int set_option(const char *name, size_t namelen, const char *value);
@@ -21,6 +24,9 @@ unsigned char* decryptdata(const unsigned char* input, size_t inputlen,
2124
unsigned char* output, size_t* outputlen);
2225
char* encryptrefname(const char* input, char* output);
2326
char* decryptrefname(const char* input, char* output);
27+
unsigned char* hashdata(const unsigned char* input, size_t inputlen,
28+
unsigned char* output);
29+
char* hashdatahex(const unsigned char* input, size_t inputlen);
2430

2531
struct options {
2632
int verbosity;
@@ -274,6 +280,21 @@ char* decryptrefname(const char* input, char* output) {
274280
return output;
275281
}
276282

283+
unsigned char* hashdata(const unsigned char* input, size_t inputlen,
284+
unsigned char* output) {
285+
struct git_hash_ctx c;
286+
hash_algos[GIT_HASH_SHA1].init_fn(&c);
287+
git_hash_update(&c, input, inputlen);
288+
git_hash_final(output, &c);
289+
return output;
290+
}
291+
292+
char* hashdatahex(const unsigned char* input, size_t inputlen) {
293+
unsigned char hash[GIT_SHA1_RAWSZ];
294+
hashdata(input, inputlen, hash);
295+
return hash_to_hex_algop(hash, &hash_algos[GIT_HASH_SHA1]);
296+
}
297+
277298
int cmd_main(int argc, const char** argv) {
278299
(void)argv;
279300
(void)argc;

0 commit comments

Comments
 (0)