diff options
| author | StevenWdV <stevenwdv@gmail.com> | 2022-01-24 14:59:25 +0100 |
|---|---|---|
| committer | StevenWdV <stevenwdv@gmail.com> | 2022-01-24 16:24:57 +0100 |
| commit | e544c6fa9e15e7277da79e2464243e90b2706b8c (patch) | |
| tree | de6613747e0e34a799089d4677f9833a85748712 /verify.go | |
| parent | aab2e4b966c82b67eb0e204060e5ea6cd4ea15cf (diff) | |
Cleanup
Added variables to Makefiles to specify custom exports/ directory;
Split exception classes in Java & C#;
Added more comments;
Renamed library and Go package;
Removed real (pure) tests;
Added generate_lib.ps1 to generate import .lib for Windows (Swift);
Moved built Go libraries to exports/lib/;
Switch to hopefully faster Swift GitHub Action.
Diffstat (limited to 'verify.go')
| -rw-r--r-- | verify.go | 50 |
1 files changed, 32 insertions, 18 deletions
@@ -1,4 +1,4 @@ -package eduvpn_verify +package eduvpn_discovery import ( "fmt" @@ -6,9 +6,17 @@ import ( "os" ) +// getKeys returns keys taken from https://git.sr.ht/~eduvpn/disco.eduvpn.org#public-keys. +func getKeys() []string { + return []string{ + "RWRtBSX1alxyGX+Xn3LuZnWUT0w//B6EmTJvgaAxBMYzlQeI+jdrO6KF", // fkooman@tuxed.net, kolla@uninett.no + "RWQKqtqvd0R7rUDp0rWzbtYPA3towPWcLDCl7eY9pBMMI/ohCmrS0WiM", // RoSp + } +} + // Verify verifies the signature (.minisig file format) on signedJson. // -// expectedFileName must be set to the file type to be verified, either server_list.json or organization_list.json. +// expectedFileName must be set to the file type to be verified, either "server_list.json" or "organization_list.json". // minSign must be set to the minimum UNIX timestamp (without milliseconds) for the file version. // This value should not be smaller than the time on the previous document verified. // @@ -16,10 +24,7 @@ import ( // // Verify is a wrapper around verifyWithKeys where allowedPublicKeys is set to the list from https://git.sr.ht/~eduvpn/disco.eduvpn.org#public-keys. func Verify(signatureFileContent string, signedJson []byte, expectedFileName string, minSignTime uint64) (bool, error) { - keyStrs := []string{ - "RWRtBSX1alxyGX+Xn3LuZnWUT0w//B6EmTJvgaAxBMYzlQeI+jdrO6KF", // fkooman@tuxed.net, kolla@uninett.no - "RWQKqtqvd0R7rUDp0rWzbtYPA3towPWcLDCl7eY9pBMMI/ohCmrS0WiM", // RoSp - } + keyStrs := getKeys() if extraKey != "" { keyStrs = append(keyStrs, extraKey) _, err := fmt.Fprintf(os.Stderr, "INSECURE TEST MODE ENABLED WITH KEY %q\n", extraKey) @@ -37,22 +42,25 @@ func Verify(signatureFileContent string, signedJson []byte, expectedFileName str return valid, nil } -// Extra allowed key for testing +// extraKey is an extra allowed key for testing. var extraKey = "" // InsecureTestingSetExtraKey adds an extra allowed key for verification with Verify. -// ONLY USE FOR TESTING. Probably not thread-safe. Do not call in parallel to Verify. +// ONLY USE FOR TESTING. Applies to all threads. Probably not thread-safe. Do not call in parallel to Verify. +// +// keyString must be a Base64-encoded Minisign key, or empty to reset. func InsecureTestingSetExtraKey(keyString string) { extraKey = keyString } -type VerifyErrorCode int +// VerifyErrorCode Simplified error code for public interface. +type VerifyErrorCode int8 const ( - ErrUnknownExpectedFileName VerifyErrorCode = iota + 1 - ErrInvalidSignature - ErrInvalidSignatureUnknownKey - ErrTooOld + ErrUnknownExpectedFileName VerifyErrorCode = iota + 1 // Unknown expected file name specified. The signature has not been verified. + ErrInvalidSignature // Signature is invalid (for the expected file type). + ErrInvalidSignatureUnknownKey // Signature was created with an unknown key and has not been verified. + ErrTooOld // Signature timestamp smaller than specified minimum signing time (rollback). ) type VerifyError struct { @@ -71,9 +79,9 @@ func (err VerifyError) Unwrap() error { // // Verification is performed using a matching key in allowedPublicKeys. // The signature is checked to be a Blake2b-prehashed Ed25519 Minisign signature with a valid trusted comment. -// The file type that is verified is indicated by expectedFileName, which must be one of server_list.json/organization_list.json. +// The file type that is verified is indicated by expectedFileName, which must be one of "server_list.json"/"organization_list.json". // The trusted comment is checked to be of the form "timestamp:<timestamp>\tfile:<expectedFileName>", optionally suffixed by something, e.g. "\thashed". -// The signature is checked to have a timestamp with a value of at least minSignTime, which is a UNIX timestamp without milliseconds; +// The signature is checked to have a timestamp with a value of at least minSignTime, which is a UNIX timestamp without milliseconds. // // The return value will either be (true, nil) on success or (false, detailedVerifyError) on failure. func verifyWithKeys(signatureFileContent string, signedJson []byte, expectedFileName string, minSignTime uint64, allowedPublicKeys []string) (bool, error) { @@ -89,18 +97,21 @@ func verifyWithKeys(signatureFileContent string, signedJson []byte, expectedFile return false, detailedVerifyError{errInvalidSignatureFormat, "invalid signature format", err} } + // Check if signature is prehashed, see https://jedisct1.github.io/minisign/#signature-format if sig.SignatureAlgorithm != [2]byte{'E', 'D'} { return false, detailedVerifyError{errInvalidSignatureAlgorithm, "BLAKE2b-prehashed EdDSA signature required", nil} } + // Find allowed key used for signature for _, keyStr := range allowedPublicKeys { key, err := minisign.NewPublicKey(keyStr) if err != nil { + // Should only happen if Verify is wrong or extraKey is invalid return false, detailedVerifyError{errInvalidPublicKey, "internal error: could not create public key", err} } if sig.KeyId != key.KeyId { - continue + continue // Wrong key } valid, err := key.Verify(signedJson, sig) @@ -108,6 +119,7 @@ func verifyWithKeys(signatureFileContent string, signedJson []byte, expectedFile return false, detailedVerifyError{errInvalidSignature, "invalid signature", err} } + // Parse trusted comment var signTime uint64 var sigFileName string // sigFileName cannot have spaces @@ -127,10 +139,12 @@ func verifyWithKeys(signatureFileContent string, signedJson []byte, expectedFile return true, nil } - return false, detailedVerifyError{errWrongKey, "signature was created with unknown key", nil} + // No matching allowed key found + return false, detailedVerifyError{errWrongKey, "signature was created with an unknown key", nil} } -type detailedVerifyErrorCode int +// detailedVerifyErrorCode used for unit tests. +type detailedVerifyErrorCode int8 const ( errUnknownExpectedFileName detailedVerifyErrorCode = iota + 1 |
