This repository has been archived by the owner on Mar 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
signature.rkt
146 lines (120 loc) · 4.33 KB
/
signature.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#lang racket/base
; Authenticate source of bytes
(require racket/contract
"crypto.rkt"
"file.rkt"
"integrity.rkt"
"integrity/ffi.rkt"
"state.rkt"
"message.rkt"
"setting.rkt"
"signature/base.rkt"
"signature/snake-oil.rkt"
"source.rkt")
(provide
(all-from-out "signature/base.rkt"
"signature/snake-oil.rkt")
(contract-out
[MAX_EXPECTED_SIGNATURE_PAYLOAD_LENGTH
budget/c]
[lock-signature
(->* (signature?)
(#:public-key-budget budget/c
#:signature-budget budget/c
exhaust/c)
signature?)]
[make-snake-oil-signature
(-> bytes? symbol? signature?)]
[call-with-snake-oil-cipher-trust
(-> (-> any) any)]
[make-signature
(->* (bytes? symbol? bytes?)
((or/c #f bytes?))
bytes?)]
[malformed-signature?
flat-contract?]
[sourced-signature?
flat-contract?]
[well-formed-signature?
flat-contract?]
[DENXI_TRUST_ANY_PUBLIC_KEY setting?]
[DENXI_TRUST_BAD_SIGNATURE setting?]
[DENXI_TRUST_PUBLIC_KEYS setting?]
[DENXI_TRUST_UNSIGNED setting?]))
(define (sourced-signature? v)
(and (signature? v)
(or (source? (signature-body v))
(source? (signature-public-key v)))))
(define well-formed-signature?
(or/c raw-signature? sourced-signature?))
(define malformed-signature?
(not/c well-formed-signature?))
(define-setting DENXI_TRUST_ANY_PUBLIC_KEY boolean? #f)
(define-setting DENXI_TRUST_BAD_SIGNATURE boolean? #f)
(define-setting DENXI_TRUST_PUBLIC_KEYS (listof well-formed-integrity?) null)
(define-setting DENXI_TRUST_UNSIGNED boolean? #f)
(define MAX_EXPECTED_SIGNATURE_PAYLOAD_LENGTH 24000)
(define (make-snake-oil-signature digest chf)
(signature snake-oil-public-key
(make-signature digest
chf
snake-oil-private-key
snake-oil-private-key-password)))
(define (call-with-snake-oil-cipher-trust f)
(call-with-snake-oil-chf-trust
(λ ()
(DENXI_TRUST_PUBLIC_KEYS
(list (integrity (get-default-chf)
(make-digest snake-oil-public-key)))
f))))
(define (make-signature . xs)
(apply (current-make-signature) xs))
(define (lock-signature siginfo
#:public-key-budget
[public-key-budget MAX_EXPECTED_SIGNATURE_PAYLOAD_LENGTH]
#:signature-budget
[signature-budget MAX_EXPECTED_SIGNATURE_PAYLOAD_LENGTH]
[exhaust raise])
(call/cc
(λ (abort)
(define (exhaust* v)
(abort (exhaust v)))
(signature
(and (signature-public-key siginfo)
(lock-source (signature-public-key siginfo)
public-key-budget
exhaust*))
(and (signature-body siginfo)
(lock-source (signature-body siginfo)
signature-budget
exhaust*))))))
(module+ test
(require rackunit
(submod "state.rkt" test)
(submod "integrity.rkt" test))
(define pubkey-bytes #"pubkey")
(define digest (call-with-snake-oil-chf-trust (λ () (make-digest #"abc"))))
(define intinfo (integrity 'snake-oil digest))
(define signature-bytes #"sig")
; The content used for the integrity info does not matter. All
; that matters is if the signature matches based on it.
(define siginfo
(signature pubkey-bytes signature-bytes))
(test-case "Lock signature info"
(define example (signature (text-source "wx") (text-source "yz")))
(define (try pb sb)
(lock-signature #:public-key-budget pb
#:signature-budget sb
example))
(check-match (try 0 0) (signature (text-source "wx") (text-source "yz")))
(check-match (try 2 2) (signature #"wx" #"yz"))
(check-match (try 0 2) (signature (text-source "wx") #"yz"))
(check-match (try 2 0) (signature #"wx" (text-source "yz")))
(test-case "Exhaust a lock on first lock-signature failure"
(define (try-exhaust p s)
(check-equal? (lock-signature (signature p s)
values)
1))
(try-exhaust (exhausted-source 1) #"")
(try-exhaust #"" (exhausted-source 1))
(try-exhaust (exhausted-source 1) (exhausted-source 2)))))