Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
authority
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
katzenpost
authority
Commits
aacc0c23
Commit
aacc0c23
authored
Oct 13, 2018
by
masala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge nonvoting/voting internal s11n
parent
098da078
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
161 additions
and
868 deletions
+161
-868
internal/s11n/descriptor.go
internal/s11n/descriptor.go
+31
-31
internal/s11n/document.go
internal/s11n/document.go
+98
-22
internal/s11n/document_test.go
internal/s11n/document_test.go
+7
-1
nonvoting/client/client.go
nonvoting/client/client.go
+1
-1
voting/client/client.go
voting/client/client.go
+6
-7
voting/client/client_test.go
voting/client/client_test.go
+3
-4
voting/internal/s11n/descriptor.go
voting/internal/s11n/descriptor.go
+0
-270
voting/internal/s11n/descriptor_test.go
voting/internal/s11n/descriptor_test.go
+0
-95
voting/internal/s11n/document.go
voting/internal/s11n/document.go
+0
-292
voting/internal/s11n/document_test.go
voting/internal/s11n/document_test.go
+0
-124
voting/server/config/config.go
voting/server/config/config.go
+2
-1
voting/server/state.go
voting/server/state.go
+5
-11
voting/server/state_test.go
voting/server/state_test.go
+7
-8
voting/server/wire_handler.go
voting/server/wire_handler.go
+1
-1
No files found.
internal/s11n/descriptor.go
View file @
aacc0c23
// descriptor.go - Katzenpost
Non-voting
authority descriptor s11n.
// Copyright (C) 2017
Yawning Angel.
// descriptor.go - Katzenpost authority descriptor s11n.
// Copyright (C) 2017
, 2018 Yawning Angel, masala, David Stainton
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
...
...
@@ -25,24 +25,24 @@ import (
"time"
"github.com/katzenpost/core/crypto/cert"
"github.com/katzenpost/core/epochtime"
"github.com/katzenpost/core/pki"
"github.com/katzenpost/core/epochtime"
"github.com/katzenpost/core/sphinx/constants"
"github.com/ugorji/go/codec"
"golang.org/x/net/idna"
)
const
(
nodeDescriptorVersion
=
"
nonvoting-
v0"
nodeDescriptorVersion
=
"v0"
)
var
(
certificateExpiration
=
(
epochtime
.
Period
*
3
)
+
(
time
.
Minute
*
10
)
// CertificateExpiration is the time a descriptor certificate will be valid for.
CertificateExpiration
=
(
epochtime
.
Period
*
3
)
+
(
time
.
Minute
*
10
)
)
type
nodeDescriptor
struct
{
// Version uniquely identifies the descriptor format as being for the
// non-voting authority so that it can be rejected when unexpectedly
// posted to, or received from an authority, or if the version changes.
// specified version so that it can be rejected if the format changes.
Version
string
pki
.
MixDescriptor
...
...
@@ -63,7 +63,7 @@ func SignDescriptor(signer cert.Signer, base *pki.MixDescriptor) ([]byte, error)
}
// Sign the descriptor.
expiration
:=
time
.
Now
()
.
Add
(
c
ertificateExpiration
)
.
Unix
()
expiration
:=
time
.
Now
()
.
Add
(
C
ertificateExpiration
)
.
Unix
()
signed
,
err
:=
cert
.
Sign
(
signer
,
payload
,
expiration
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -94,7 +94,7 @@ func GetVerifierFromDescriptor(rawDesc []byte) (cert.Verifier, error) {
func
VerifyAndParseDescriptor
(
verifier
cert
.
Verifier
,
b
[]
byte
,
epoch
uint64
)
(
*
pki
.
MixDescriptor
,
error
)
{
signatures
,
err
:=
cert
.
GetSignatures
(
b
)
if
len
(
signatures
)
!=
1
{
return
nil
,
fmt
.
Errorf
(
"
nonvoting:
Expected 1 signature, got: %v"
,
len
(
signatures
))
return
nil
,
fmt
.
Errorf
(
"Expected 1 signature, got: %v"
,
len
(
signatures
))
}
// Verify that the descriptor is signed by the verifier.
...
...
@@ -112,7 +112,7 @@ func VerifyAndParseDescriptor(verifier cert.Verifier, b []byte, epoch uint64) (*
// Ensure the descriptor is well formed.
if
d
.
Version
!=
nodeDescriptorVersion
{
return
nil
,
fmt
.
Errorf
(
"
nonvoting:
Invalid Descriptor Version: '%v'"
,
d
.
Version
)
return
nil
,
fmt
.
Errorf
(
"Invalid Descriptor Version: '%v'"
,
d
.
Version
)
}
if
err
=
IsDescriptorWellFormed
(
&
d
.
MixDescriptor
,
epoch
);
err
!=
nil
{
return
nil
,
err
...
...
@@ -125,38 +125,38 @@ func VerifyAndParseDescriptor(verifier cert.Verifier, b []byte, epoch uint64) (*
// a PKI Document.
func
IsDescriptorWellFormed
(
d
*
pki
.
MixDescriptor
,
epoch
uint64
)
error
{
if
d
.
Name
==
""
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor missing Name"
)
return
fmt
.
Errorf
(
"Descriptor missing Name"
)
}
if
len
(
d
.
Name
)
>
constants
.
NodeIDLength
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor Name '%v' exceeds max length"
,
d
.
Name
)
return
fmt
.
Errorf
(
"Descriptor Name '%v' exceeds max length"
,
d
.
Name
)
}
if
d
.
LinkKey
==
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor missing LinkKey"
)
return
fmt
.
Errorf
(
"Descriptor missing LinkKey"
)
}
if
d
.
IdentityKey
==
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor missing IdentityKey"
)
return
fmt
.
Errorf
(
"Descriptor missing IdentityKey"
)
}
if
d
.
MixKeys
[
epoch
]
==
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor missing MixKey[%v]"
,
epoch
)
return
fmt
.
Errorf
(
"Descriptor missing MixKey[%v]"
,
epoch
)
}
for
e
:=
range
d
.
MixKeys
{
// TODO: Should this check that the epochs in MixKey are sequential?
if
e
<
epoch
||
e
>=
epoch
+
3
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains MixKey for invalid epoch: %v"
,
d
)
return
fmt
.
Errorf
(
"Descriptor contains MixKey for invalid epoch: %v"
,
d
)
}
}
if
len
(
d
.
Addresses
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor missing Addresses"
)
return
fmt
.
Errorf
(
"Descriptor missing Addresses"
)
}
for
transport
,
addrs
:=
range
d
.
Addresses
{
if
len
(
addrs
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains empty Address list for transport '%v'"
,
transport
)
return
fmt
.
Errorf
(
"Descriptor contains empty Address list for transport '%v'"
,
transport
)
}
var
expectedIPVer
int
switch
transport
{
case
pki
.
TransportInvalid
:
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid Transport"
)
return
fmt
.
Errorf
(
"Descriptor contains invalid Transport"
)
case
pki
.
TransportTCPv4
:
expectedIPVer
=
4
case
pki
.
TransportTCPv6
:
...
...
@@ -165,7 +165,7 @@ func IsDescriptorWellFormed(d *pki.MixDescriptor, epoch uint64) error {
// Unknown transports are only supported between the client and
// provider.
if
d
.
Layer
!=
pki
.
LayerProvider
{
return
fmt
.
Errorf
(
"
nonvoting:
Non-provider published Transport '%v'"
,
transport
)
return
fmt
.
Errorf
(
"Non-provider published Transport '%v'"
,
transport
)
}
if
transport
!=
pki
.
TransportTCP
{
// Ignore transports that don't have validation logic.
...
...
@@ -177,47 +177,47 @@ func IsDescriptorWellFormed(d *pki.MixDescriptor, epoch uint64) error {
for
_
,
v
:=
range
addrs
{
h
,
p
,
err
:=
net
.
SplitHostPort
(
v
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
}
if
len
(
h
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v'"
,
transport
,
v
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v'"
,
transport
,
v
)
}
if
port
,
err
:=
strconv
.
ParseUint
(
p
,
10
,
16
);
err
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
}
else
if
port
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': port is 0"
,
transport
,
v
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': port is 0"
,
transport
,
v
)
}
switch
expectedIPVer
{
case
4
,
6
:
if
ver
,
err
:=
getIPVer
(
h
);
err
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
}
else
if
ver
!=
expectedIPVer
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': IP version mismatch"
,
transport
,
v
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': IP version mismatch"
,
transport
,
v
)
}
default
:
// This must be TransportTCP or something else that supports
// "sensible" DNS style hostnames. Validate that they are
// at least somewhat well formed.
if
_
,
err
:=
idna
.
Lookup
.
ToASCII
(
h
);
err
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
return
fmt
.
Errorf
(
"Descriptor contains invalid address ['%v']'%v': %v"
,
transport
,
v
,
err
)
}
}
}
}
if
len
(
d
.
Addresses
[
pki
.
TransportTCPv4
])
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains no TCPv4 addresses"
)
return
fmt
.
Errorf
(
"Descriptor contains no TCPv4 addresses"
)
}
switch
d
.
Layer
{
case
0
:
if
d
.
Kaetzchen
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains Kaetzchen when a mix"
)
return
fmt
.
Errorf
(
"Descriptor contains Kaetzchen when a mix"
)
}
case
pki
.
LayerProvider
:
if
err
:=
validateKaetzchen
(
d
.
Kaetzchen
);
err
!=
nil
{
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor contains invalid Kaetzchen block: %v"
,
err
)
return
fmt
.
Errorf
(
"Descriptor contains invalid Kaetzchen block: %v"
,
err
)
}
default
:
return
fmt
.
Errorf
(
"
nonvoting:
Descriptor self-assigned Layer: '%v'"
,
d
.
Layer
)
return
fmt
.
Errorf
(
"Descriptor self-assigned Layer: '%v'"
,
d
.
Layer
)
}
return
nil
}
...
...
internal/s11n/document.go
View file @
aacc0c23
// document.go - Katzenpost
Non-voting
authority document s11n.
// Copyright (C) 2017
Yawning Angel.
// document.go - Katzenpost authority document s11n.
// Copyright (C) 2017
, 2018 Yawning Angel, masala, David Stainton
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
...
...
@@ -17,21 +17,30 @@
package
s11n
import
(
"encoding/binary"
"errors"
"fmt"
"time"
"github.com/katzenpost/core/crypto/cert"
"github.com/katzenpost/core/epochtime"
"github.com/katzenpost/core/pki"
"github.com/ugorji/go/codec"
)
const
documentVersion
=
"nonvoting-document-v0"
const
(
// DocumentVersion is the string identifying the format of the Document
DocumentVersion
=
"document-v0"
// SharedRandomLength is the length in bytes of a SharedRandomCommit.
SharedRandomLength
=
40
// SharedRandomValueLength is the length in bytes of a SharedRandomValue.
SharedRandomValueLength
=
32
)
var
(
// ErrInvalidEpoch is the error to return when the document epoch is
// invalid.
ErrInvalidEpoch
=
errors
.
New
(
"
nonvoting:
invalid document epoch"
)
ErrInvalidEpoch
=
errors
.
New
(
"invalid document epoch"
)
jsonHandle
*
codec
.
JsonHandle
)
...
...
@@ -39,8 +48,7 @@ var (
// Document is the on-the-wire representation of a PKI Document.
type
Document
struct
{
// Version uniquely identifies the document format as being for the
// non-voting authority so that it can be rejected when unexpectedly
// received or if the version changes.
// specified version so that it can be rejected if the format changes.
Version
string
Epoch
uint64
...
...
@@ -59,11 +67,28 @@ type Document struct {
Topology
[][][]
byte
Providers
[][]
byte
SharedRandomCommit
[]
byte
SharedRandomValue
[]
byte
}
// FromPayload deserializes, then verifies a Document, and returns the Document or error.
func
FromPayload
(
verifier
cert
.
Verifier
,
payload
[]
byte
)
(
*
Document
,
error
)
{
verified
,
err
:=
cert
.
Verify
(
verifier
,
payload
)
if
err
!=
nil
{
return
nil
,
err
}
dec
:=
codec
.
NewDecoderBytes
(
verified
,
jsonHandle
)
d
:=
new
(
Document
)
if
err
:=
dec
.
Decode
(
d
);
err
!=
nil
{
return
nil
,
err
}
return
d
,
nil
}
// SignDocument signs and serializes the document with the provided signing key.
func
SignDocument
(
signer
cert
.
Signer
,
d
*
Document
)
([]
byte
,
error
)
{
d
.
Version
=
d
ocumentVersion
d
.
Version
=
D
ocumentVersion
// Serialize the document.
var
payload
[]
byte
...
...
@@ -73,18 +98,43 @@ func SignDocument(signer cert.Signer, d *Document) ([]byte, error) {
}
// Sign the document.
expiration
:=
time
.
Now
()
.
Add
(
c
ertificateExpiration
)
.
Unix
()
expiration
:=
time
.
Now
()
.
Add
(
C
ertificateExpiration
)
.
Unix
()
return
cert
.
Sign
(
signer
,
payload
,
expiration
)
}
// MultiSignDocument signs and serializes the document with the provided signing key, adding the signature to the existing signatures.
func
MultiSignDocument
(
signer
cert
.
Signer
,
peerSignatures
[]
*
cert
.
Signature
,
verifiers
map
[
string
]
cert
.
Verifier
,
d
*
Document
)
([]
byte
,
error
)
{
d
.
Version
=
DocumentVersion
// Serialize the document.
var
payload
[]
byte
enc
:=
codec
.
NewEncoderBytes
(
&
payload
,
jsonHandle
)
if
err
:=
enc
.
Encode
(
d
);
err
!=
nil
{
return
nil
,
err
}
// Sign the document.
expiration
:=
time
.
Now
()
.
Add
(
3
*
epochtime
.
Period
)
.
Unix
()
signed
,
err
:=
cert
.
Sign
(
signer
,
payload
,
expiration
)
if
err
!=
nil
{
return
nil
,
err
}
// attach peer signatures
for
_
,
signature
:=
range
peerSignatures
{
s
:=
string
(
signature
.
Identity
)
verifier
:=
verifiers
[
s
]
signed
,
err
=
cert
.
AddSignature
(
verifier
,
*
signature
,
signed
)
if
err
!=
nil
{
return
nil
,
err
}
}
return
signed
,
nil
}
// VerifyAndParseDocument verifies the signautre and deserializes the document.
func
VerifyAndParseDocument
(
b
[]
byte
,
verifier
cert
.
Verifier
)
(
*
pki
.
Document
,
error
)
{
// Sanity check the number of signatures, and
// validate the signature with the provided public key.
signatures
,
err
:=
cert
.
GetSignatures
(
b
)
if
len
(
signatures
)
!=
1
{
return
nil
,
fmt
.
Errorf
(
"nonvoting: Expected 1 signature, got: %v"
,
len
(
signatures
))
}
payload
,
err
:=
cert
.
Verify
(
verifier
,
b
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -98,13 +148,39 @@ func VerifyAndParseDocument(b []byte, verifier cert.Verifier) (*pki.Document, er
}
// Ensure the document is well formed.
if
d
.
Version
!=
d
ocumentVersion
{
return
nil
,
fmt
.
Errorf
(
"
nonvoting:
Invalid Document Version: '%v'"
,
d
.
Version
)
if
d
.
Version
!=
D
ocumentVersion
{
return
nil
,
fmt
.
Errorf
(
"Invalid Document Version: '%v'"
,
d
.
Version
)
}
// Convert from the wire representation to a Document, and validate
// everything.
// If there is a SharedRandomCommit, verify the Epoch contained in SharedRandomCommit matches the Epoch in the Document.
if
len
(
d
.
SharedRandomCommit
)
==
SharedRandomLength
{
srvEpoch
:=
binary
.
BigEndian
.
Uint64
(
d
.
SharedRandomCommit
[
0
:
8
])
if
srvEpoch
!=
d
.
Epoch
{
return
nil
,
fmt
.
Errorf
(
"Document with invalid Epoch in SharedRandomCommit"
)
}
}
if
len
(
d
.
SharedRandomValue
)
!=
SharedRandomValueLength
{
if
len
(
d
.
SharedRandomValue
)
!=
0
{
return
nil
,
fmt
.
Errorf
(
"Document has invalid SharedRandomValue"
)
}
else
if
len
(
d
.
SharedRandomCommit
)
!=
SharedRandomLength
{
return
nil
,
fmt
.
Errorf
(
"Document has invalid SharedRandomCommit"
)
}
}
if
len
(
d
.
SharedRandomCommit
)
!=
SharedRandomLength
{
if
len
(
d
.
SharedRandomCommit
)
!=
0
{
return
nil
,
fmt
.
Errorf
(
"Document has invalid SharedRandomCommit"
)
}
else
if
len
(
d
.
SharedRandomValue
)
!=
SharedRandomValueLength
{
return
nil
,
fmt
.
Errorf
(
"Document has invalid SharedRandomValue"
)
}
}
doc
:=
new
(
pki
.
Document
)
doc
.
SharedRandomCommit
=
d
.
SharedRandomCommit
doc
.
SharedRandomValue
=
d
.
SharedRandomValue
doc
.
Epoch
=
d
.
Epoch
doc
.
SendRatePerMinute
=
d
.
SendRatePerMinute
doc
.
MixLambda
=
d
.
MixLambda
...
...
@@ -163,11 +239,11 @@ func VerifyAndParseDocument(b []byte, verifier cert.Verifier) (*pki.Document, er
func
IsDocumentWellFormed
(
d
*
pki
.
Document
)
error
{
pks
:=
make
(
map
[
string
]
bool
)
if
len
(
d
.
Topology
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Document contains no Topology"
)
return
fmt
.
Errorf
(
"Document contains no Topology"
)
}
for
layer
,
nodes
:=
range
d
.
Topology
{
if
len
(
nodes
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Document Topology layer %d contains no nodes"
,
layer
)
return
fmt
.
Errorf
(
"Document Topology layer %d contains no nodes"
,
layer
)
}
for
_
,
desc
:=
range
nodes
{
if
err
:=
IsDescriptorWellFormed
(
desc
,
d
.
Epoch
);
err
!=
nil
{
...
...
@@ -175,24 +251,24 @@ func IsDocumentWellFormed(d *pki.Document) error {
}
pk
:=
string
(
desc
.
IdentityKey
.
Identity
())
if
_
,
ok
:=
pks
[
pk
];
ok
{
return
fmt
.
Errorf
(
"
nonvoting:
Document contains multiple entries for %v"
,
desc
.
IdentityKey
)
return
fmt
.
Errorf
(
"Document contains multiple entries for %v"
,
desc
.
IdentityKey
)
}
pks
[
pk
]
=
true
}
}
if
len
(
d
.
Providers
)
==
0
{
return
fmt
.
Errorf
(
"
nonvoting:
Document contains no Providers"
)
return
fmt
.
Errorf
(
"Document contains no Providers"
)
}
for
_
,
desc
:=
range
d
.
Providers
{
if
err
:=
IsDescriptorWellFormed
(
desc
,
d
.
Epoch
);
err
!=
nil
{
return
err
}
if
desc
.
Layer
!=
pki
.
LayerProvider
{
return
fmt
.
Errorf
(
"
nonvoting:
Document lists %v as a Provider with layer %v"
,
desc
.
IdentityKey
,
desc
.
Layer
)
return
fmt
.
Errorf
(
"Document lists %v as a Provider with layer %v"
,
desc
.
IdentityKey
,
desc
.
Layer
)
}
pk
:=
string
(
desc
.
IdentityKey
.
Identity
())
if
_
,
ok
:=
pks
[
pk
];
ok
{
return
fmt
.
Errorf
(
"
nonvoting:
Document contains multiple entries for %v"
,
desc
.
IdentityKey
)
return
fmt
.
Errorf
(
"Document contains multiple entries for %v"
,
desc
.
IdentityKey
)
}
pks
[
pk
]
=
true
}
...
...
internal/s11n/document_test.go
View file @
aacc0c23
// document_test.go - Document s11n tests.
// Copyright (C) 2017 Yawning Angel
// Copyright (C) 2017 Yawning Angel
, masala, David Stainton
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
...
...
@@ -18,6 +18,7 @@ package s11n
import
(
"crypto/rand"
"encoding/binary"
"fmt"
"testing"
...
...
@@ -73,6 +74,9 @@ func TestDocument(t *testing.T) {
require
.
NoError
(
err
,
"eddsa.NewKeypair()"
)
testSendRate
:=
uint64
(
3
)
sharedRandomCommit
:=
make
([]
byte
,
SharedRandomLength
)
binary
.
BigEndian
.
PutUint64
(
sharedRandomCommit
[
:
8
],
debugTestEpoch
)
// Generate a Document.
doc
:=
&
Document
{
...
...
@@ -83,6 +87,8 @@ func TestDocument(t *testing.T) {
MixMaxDelay
:
23
,
SendLambda
:
0.69
,
SendMaxInterval
:
17
,
SharedRandomCommit
:
sharedRandomCommit
,
SharedRandomValue
:
make
([]
byte
,
SharedRandomValueLength
),
}
idx
:=
1
for
l
:=
0
;
l
<
3
;
l
++
{
...
...
nonvoting/client/client.go
View file @
aacc0c23
...
...
@@ -24,7 +24,7 @@ import (
"fmt"
"net"
"github.com/katzenpost/authority/
nonvoting/
internal/s11n"
"github.com/katzenpost/authority/internal/s11n"
"github.com/katzenpost/core/crypto/ecdh"
"github.com/katzenpost/core/crypto/eddsa"
"github.com/katzenpost/core/crypto/rand"
...
...
voting/client/client.go
View file @
aacc0c23
...
...
@@ -25,7 +25,7 @@ import (
//mrand "math/rand"
"net"
"github.com/katzenpost/authority/
voting/
internal/s11n"
"github.com/katzenpost/authority/internal/s11n"
"github.com/katzenpost/authority/voting/server/config"
"github.com/katzenpost/core/crypto/cert"
"github.com/katzenpost/core/crypto/ecdh"
...
...
@@ -104,6 +104,7 @@ type connector struct {
log
*
logging
.
Logger
}
// NewConnector returns a connector initialized from a Config.
func
NewConnector
(
cfg
*
Config
)
*
connector
{
p
:=
&
connector
{
cfg
:
cfg
,
...
...
@@ -174,7 +175,7 @@ func (p *connector) initSession(ctx context.Context, doneCh <-chan interface{},
},
nil
}
func
(
c
*
connector
)
roundTrip
(
s
*
wire
.
Session
,
cmd
commands
.
Command
)
(
commands
.
Command
,
error
)
{
func
(
p
*
connector
)
roundTrip
(
s
*
wire
.
Session
,
cmd
commands
.
Command
)
(
commands
.
Command
,
error
)
{
if
err
:=
s
.
SendCommand
(
cmd
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -269,10 +270,8 @@ func (c *client) Post(ctx context.Context, epoch uint64, signingKey *eddsa.Priva
}
if
len
(
errs
)
==
0
{
return
nil
}
else
{
return
fmt
.
Errorf
(
"failure to Post to %d Directory Authorities"
,
len
(
errs
))
}
// NOTREACHED
return
fmt
.
Errorf
(
"failure to Post to %d Directory Authorities"
,
len
(
errs
))
}
// Get returns the PKI document along with the raw serialized form for the provided epoch.
...
...
@@ -325,7 +324,7 @@ func (c *client) Get(ctx context.Context, epoch uint64) (*pki.Document, []byte,
if
len
(
good
)
==
len
(
c
.
cfg
.
Authorities
)
{
c
.
log
.
Notice
(
"OK, received fully signed consensus document."
)
}
doc
,
_
,
err
=
s11n
.
VerifyAndParseDocument
(
r
.
Payload
,
c
.
cfg
.
Authorities
[
0
]
.
IdentityPublicKey
)
doc
,
err
=
s11n
.
VerifyAndParseDocument
(
r
.
Payload
,
c
.
cfg
.
Authorities
[
0
]
.
IdentityPublicKey
)
if
err
!=
nil
{
// XXX: somehow this returned a nil doc!
return
nil
,
nil
,
err
...
...
@@ -342,7 +341,7 @@ func (c *client) Get(ctx context.Context, epoch uint64) (*pki.Document, []byte,
// Deserialize returns PKI document given the raw bytes.
func
(
c
*
client
)
Deserialize
(
raw
[]
byte
)
(
*
pki
.
Document
,
error
)
{
doc
,
_
,
err
:=
s11n
.
VerifyAndParseDocument
(
raw
,
c
.
cfg
.
Authorities
[
0
]
.
IdentityPublicKey
)
doc
,
err
:=
s11n
.
VerifyAndParseDocument
(
raw
,
c
.
cfg
.
Authorities
[
0
]
.
IdentityPublicKey
)
if
err
!=
nil
{
fmt
.
Errorf
(
"Deserialize failure: %s"
,
err
)
}
...
...
voting/client/client_test.go
View file @
aacc0c23
// client.go - Katzenpost
non-
voting authority client.
// client.go - Katzenpost voting authority client.
// Copyright (C) 2018 David Stainton
//
// This program is free software: you can redistribute it and/or modify
...
...
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Package client implements the Katzenpost
non-
voting authority client.
// Package client implements the Katzenpost voting authority client.
package
client
import
(
...
...
@@ -26,7 +26,7 @@ import (
"testing"
"time"
"github.com/katzenpost/authority/
voting/
internal/s11n"
"github.com/katzenpost/authority/internal/s11n"
"github.com/katzenpost/authority/voting/server/config"
"github.com/katzenpost/core/crypto/cert"
"github.com/katzenpost/core/crypto/ecdh"
...
...
@@ -207,7 +207,6 @@ func generateMixnet(numMixes, numProviders int, epoch uint64) (*s11n.Document, e
MixLambda
:
0.25
,
MixMaxDelay
:
4000
,
SendLambda
:
1.2
,
SendShift
:
3
,
SendMaxInterval
:
300
,
Topology
:
topology
,
Providers
:
providersRaw
,
...
...
voting/internal/s11n/descriptor.go
deleted
100644 → 0
View file @
098da078
// descriptor.go - Katzenpost voting authority descriptor s11n.
// Copyright (C) 2017, 2018 Yawning Angel, masala, David Stainton
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Package s11n implements serialization routines for the various PKI
// data structures.
package
s11n
import
(
"fmt"
"net"
"strconv"
"time"
"github.com/katzenpost/core/crypto/cert"
"github.com/katzenpost/core/pki"
"github.com/katzenpost/core/epochtime"
"github.com/katzenpost/core/sphinx/constants"
"github.com/ugorji/go/codec"
"golang.org/x/net/idna"
)
const
(
nodeDescriptorVersion
=
"voting-v0"
// XXX: How many epochs should this be?
)
type
nodeDescriptor
struct
{
// Version uniquely identifies the descriptor format as being for the
// voting authority so that it can be rejected when unexpectedly
// posted to, or received from an authority, or if the version changes.
Version
string
pki
.
MixDescriptor
}
// SignDescriptor signs and serializes the descriptor with the provided signing
// key.
func
SignDescriptor
(
signer
cert
.
Signer
,
base
*
pki
.
MixDescriptor
)
([]
byte
,
error
)
{
d
:=
new
(
nodeDescriptor
)
d
.
MixDescriptor
=
*
base
d
.
Version
=
nodeDescriptorVersion
// Serialize the descriptor.
var
payload
[]
byte
enc
:=
codec
.
NewEncoderBytes
(
&
payload
,
jsonHandle
)
if
err
:=
enc
.
Encode
(
d
);
err
!=
nil
{
return
nil
,
err
}
// Sign the descriptor.
expiration
:=
time
.
Now
()
.
Add
(
3
*
epochtime
.
Period
)
.
Unix
()
signed
,
err
:=
cert
.
Sign
(
signer
,
payload
,
expiration
)
if
err
!=
nil
{
return
nil
,
err
}
return
signed
,
nil
}
// GetVerifierFromDescriptor returns a verifier for the given
// mix descriptor certificate.
func
GetVerifierFromDescriptor
(
rawDesc
[]
byte
)
(
cert
.
Verifier
,
error
)
{
payload
,
err
:=
cert
.
GetCertified
(
rawDesc
)
if
err
!=
nil
{
return
nil
,
err
}
// Parse the payload.
d
:=
new
(
nodeDescriptor
)
dec
:=
codec
.
NewDecoderBytes
(
payload
,
jsonHandle
)
if
err
=
dec
.
Decode
(
d
);
err
!=
nil
{
return
nil
,
err
}
return
d
.
IdentityKey
,
nil
}
// VerifyAndParseDescriptor verifies the signature and deserializes the
// descriptor. MixDescriptors returned from this routine are guaranteed
// to have been correctly self signed by the IdentityKey listed in the
// MixDescriptor.
func
VerifyAndParseDescriptor
(
verifier
cert
.
Verifier
,
b
[]
byte
,
epoch
uint64
)
(
*
pki
.
MixDescriptor
,
error
)
{
signatures
,
err
:=
cert
.
GetSignatures
(
b
)
if
len
(
signatures
)
!=
1
{
return
nil
,
fmt
.
Errorf
(
"voting: Expected 1 signature, got: %v"
,
len
(
signatures
))
}
// Verify that the descriptor is signed by the verifier.
payload
,
err
:=
cert
.
Verify
(
verifier
,
b
)
if
err
!=
nil
{
return
nil
,
err
}
// Parse the payload.
d
:=
new
(
nodeDescriptor
)
dec
:=
codec
.
NewDecoderBytes
(
payload
,
jsonHandle
)
if
err
=
dec
.
Decode
(
d
);
err
!=
nil
{
return
nil
,
err
}
// Ensure the descriptor is well formed.
if
d
.
Version
!=
nodeDescriptorVersion
{
return
nil
,
fmt
.
Errorf
(
"voting: Invalid Descriptor Version: '%v'"
,
d
.
Version
)
}
if
err
=
IsDescriptorWellFormed
(
&
d
.
MixDescriptor
,
epoch
);
err
!=
nil
{
return
nil
,
err
}
return
&
d
.
MixDescriptor
,
nil
}