Merge pull request 'Update Code Exerpts' (#117) from issue-111-excerpts into master
Reviewed-on: #117master
commit
32b4d7f35b
@ -0,0 +1,76 @@
|
||||
-- This file is under BSD License 2.0
|
||||
|
||||
-- Sync protocol for p≡p
|
||||
-- Copyright (c) 2016-2021 p≡p foundation
|
||||
|
||||
-- Written by Volker Birk
|
||||
|
||||
PEP
|
||||
{ iso(1) org(3) dod(6) internet(1) private(4)
|
||||
enterprise(1) pEp(47878) basic(0) }
|
||||
|
||||
DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
EXPORTS Identity, IdentityList, TID, Hash, Version, Rating, PString,
|
||||
PStringList, PStringPair, PStringPairList, ISO639-1;
|
||||
|
||||
ISO639-1 ::= PrintableString(FROM ("a".."z")) (SIZE(2))
|
||||
Hex ::= PrintableString(FROM ("A".."F" | "0".."9"))
|
||||
Hash ::= Hex(SIZE(16..128)) -- 32bit Key ID to SHA512 in hex
|
||||
PString ::= UTF8String (SIZE(0..1024))
|
||||
PStringList ::= SEQUENCE OF PString
|
||||
TID ::= OCTET STRING (SIZE(16)) -- UUID version 4 variant 1
|
||||
|
||||
Identity ::= SEQUENCE {
|
||||
address PString,
|
||||
fpr Hash,
|
||||
user-id PString,
|
||||
username PString,
|
||||
comm-type INTEGER (0..255),
|
||||
lang ISO639-1
|
||||
}
|
||||
|
||||
IdentityList ::= SEQUENCE OF Identity
|
||||
|
||||
Version ::= SEQUENCE {
|
||||
major INTEGER (0..255) DEFAULT 1,
|
||||
minor INTEGER (0..255) DEFAULT 2
|
||||
}
|
||||
|
||||
Rating ::= ENUMERATED {
|
||||
-- no color
|
||||
|
||||
cannot-decrypt (1),
|
||||
have-no-key (2),
|
||||
unencrypted (3),
|
||||
unreliable (5),
|
||||
|
||||
b0rken (-2),
|
||||
|
||||
-- yellow
|
||||
|
||||
reliable (6),
|
||||
|
||||
-- green
|
||||
|
||||
trusted (7),
|
||||
trusted-and-anonymized (8),
|
||||
fully-anonymous (9),
|
||||
|
||||
-- red
|
||||
|
||||
mistrust (-1),
|
||||
under-attack (-3)
|
||||
}
|
||||
|
||||
PStringPair ::= SEQUENCE {
|
||||
key PString,
|
||||
value PString
|
||||
}
|
||||
|
||||
PStringPairList ::= SEQUENCE OF PStringPair
|
||||
|
||||
END
|
||||
|
@ -0,0 +1,694 @@
|
||||
// This file is under BSD License 2.0
|
||||
|
||||
// Sync protocol for p≡p
|
||||
// Copyright (c) 2016-2020, p≡p foundation
|
||||
|
||||
// Written by Volker Birk
|
||||
|
||||
include ./fsm.yml2
|
||||
|
||||
protocol Sync 1 {
|
||||
// all messages have a timestamp,
|
||||
// time out and are removed after timeout
|
||||
|
||||
fsm KeySync 1, threshold=300 {
|
||||
version 1, 2;
|
||||
|
||||
state InitState {
|
||||
on Init {
|
||||
if deviceGrouped {
|
||||
send SynchronizeGroupKeys;
|
||||
go Grouped;
|
||||
}
|
||||
do newChallengeAndNegotiationBase;
|
||||
debug > initial Beacon
|
||||
send Beacon;
|
||||
go Sole;
|
||||
}
|
||||
}
|
||||
|
||||
state Sole timeout=off {
|
||||
on Init {
|
||||
do showBeingSole;
|
||||
}
|
||||
|
||||
on KeyGen {
|
||||
debug > key generated
|
||||
send Beacon;
|
||||
}
|
||||
|
||||
on CannotDecrypt {
|
||||
debug > cry, baby
|
||||
send Beacon;
|
||||
}
|
||||
|
||||
on Beacon {
|
||||
if sameChallenge {
|
||||
debug > this is our own Beacon; ignore
|
||||
}
|
||||
else {
|
||||
if weAreOfferer {
|
||||
do useOwnChallenge;
|
||||
debug > we are Offerer
|
||||
send Beacon;
|
||||
}
|
||||
else /* we are requester */ {
|
||||
do openNegotiation;
|
||||
do tellWeAreNotGrouped;
|
||||
// requester is sending NegotiationRequest
|
||||
do useOwnResponse;
|
||||
send NegotiationRequest;
|
||||
do useOwnChallenge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we get this from another sole device
|
||||
on NegotiationRequest {
|
||||
if sameChallenge { // challenge accepted
|
||||
do storeNegotiation;
|
||||
// offerer is accepting by confirming NegotiationOpen
|
||||
// repeating response is implicit
|
||||
send NegotiationOpen;
|
||||
go HandshakingOfferer;
|
||||
}
|
||||
}
|
||||
|
||||
// we get this from an existing device group
|
||||
on NegotiationRequestGrouped {
|
||||
if sameChallenge { // challenge accepted
|
||||
do storeNegotiation;
|
||||
// offerer is accepting by confirming NegotiationOpen
|
||||
// repeating response is implicit
|
||||
send NegotiationOpen;
|
||||
go HandshakingToJoin;
|
||||
}
|
||||
}
|
||||
|
||||
on NegotiationOpen {
|
||||
if sameResponse {
|
||||
debug > Requester is receiving NegotiationOpen
|
||||
do storeNegotiation;
|
||||
go HandshakingRequester;
|
||||
}
|
||||
else {
|
||||
debug > cannot approve NegotiationOpen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handshaking without existing Device group
|
||||
state HandshakingOfferer timeout=600 {
|
||||
on Init
|
||||
do showSoleHandshake;
|
||||
|
||||
// Cancel is Rollback
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Rollback {
|
||||
if sameNegotiation
|
||||
go Sole;
|
||||
}
|
||||
|
||||
// Reject is CommitReject
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
// Accept means init Phase1Commit
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
go HandshakingPhase1Offerer;
|
||||
}
|
||||
|
||||
// got a CommitAccept from requester
|
||||
on CommitAcceptRequester {
|
||||
if sameNegotiation
|
||||
go HandshakingPhase2Offerer;
|
||||
}
|
||||
}
|
||||
|
||||
// handshaking without existing Device group
|
||||
state HandshakingRequester timeout=600 {
|
||||
on Init
|
||||
do showSoleHandshake;
|
||||
|
||||
// Cancel is Rollback
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Rollback {
|
||||
if sameNegotiation
|
||||
go Sole;
|
||||
}
|
||||
|
||||
// Reject is CommitReject
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
// Accept means init Phase1Commit
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
send CommitAcceptRequester;
|
||||
go HandshakingPhase1Requester;
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingPhase1Offerer {
|
||||
on Rollback {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
go Sole;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitAcceptRequester {
|
||||
if sameNegotiation {
|
||||
send CommitAcceptOfferer;
|
||||
go FormingGroupOfferer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingPhase1Requester {
|
||||
on Rollback {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
go Sole;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitAcceptOfferer {
|
||||
if sameNegotiation {
|
||||
do prepareOwnKeys;
|
||||
send OwnKeysRequester;
|
||||
go FormingGroupRequester;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingPhase2Offerer {
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
send CommitAcceptOfferer;
|
||||
go FormingGroupOfferer;
|
||||
}
|
||||
}
|
||||
|
||||
state FormingGroupOfferer {
|
||||
on Init {
|
||||
// we need to keep in memory which keys
|
||||
// we have before forming a new group
|
||||
do prepareOwnKeys;
|
||||
do backupOwnKeys;
|
||||
}
|
||||
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Rollback
|
||||
go Sole;
|
||||
|
||||
on OwnKeysRequester {
|
||||
if sameNegotiationAndPartner {
|
||||
do saveGroupKeys;
|
||||
do receivedKeysAreDefaultKeys;
|
||||
// send the keys we had before forming a new group
|
||||
do prepareOwnKeysFromBackup;
|
||||
send OwnKeysOfferer;
|
||||
do showGroupCreated;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state FormingGroupRequester {
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Rollback
|
||||
go Sole;
|
||||
|
||||
on OwnKeysOfferer {
|
||||
if sameNegotiation {
|
||||
do saveGroupKeys;
|
||||
do prepareOwnKeys;
|
||||
do ownKeysAreDefaultKeys;
|
||||
do showGroupCreated;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state Grouped timeout=off {
|
||||
on Init {
|
||||
do newChallengeAndNegotiationBase;
|
||||
do showBeingInGroup;
|
||||
}
|
||||
|
||||
on CannotDecrypt {
|
||||
debug > cry, baby
|
||||
send SynchronizeGroupKeys;
|
||||
}
|
||||
|
||||
on SynchronizeGroupKeys {
|
||||
do prepareOwnKeys;
|
||||
send GroupKeysUpdate;
|
||||
}
|
||||
|
||||
on GroupKeysUpdate {
|
||||
if fromGroupMember // double check
|
||||
do saveGroupKeys;
|
||||
}
|
||||
|
||||
on KeyGen {
|
||||
do prepareOwnKeys;
|
||||
send GroupKeysUpdate;
|
||||
}
|
||||
|
||||
on Beacon {
|
||||
do openNegotiation;
|
||||
do tellWeAreGrouped;
|
||||
do useOwnResponse;
|
||||
send NegotiationRequestGrouped;
|
||||
do useOwnChallenge;
|
||||
}
|
||||
|
||||
on NegotiationOpen {
|
||||
if sameResponse {
|
||||
do storeNegotiation;
|
||||
do useThisKey;
|
||||
send GroupHandshake;
|
||||
go HandshakingGrouped;
|
||||
}
|
||||
else {
|
||||
debug > cannot approve NegotiationOpen
|
||||
}
|
||||
}
|
||||
|
||||
on GroupHandshake {
|
||||
do storeNegotiation;
|
||||
do storeThisKey;
|
||||
go HandshakingGrouped;
|
||||
}
|
||||
|
||||
on GroupTrustThisKey {
|
||||
if fromGroupMember // double check
|
||||
do trustThisKey;
|
||||
}
|
||||
|
||||
on LeaveDeviceGroup {
|
||||
send InitUnledGroupKeyReset;
|
||||
do disable;
|
||||
do resetOwnKeysUngrouped;
|
||||
}
|
||||
|
||||
on InitUnledGroupKeyReset {
|
||||
debug > unled group key reset; new group keys will be elected
|
||||
do useOwnResponse;
|
||||
send ElectGroupKeyResetLeader;
|
||||
go GroupKeyResetElection;
|
||||
}
|
||||
}
|
||||
|
||||
state GroupKeyResetElection {
|
||||
on ElectGroupKeyResetLeader {
|
||||
if sameResponse {
|
||||
// the first one is from us, we're leading this
|
||||
do resetOwnGroupedKeys;
|
||||
go Grouped;
|
||||
}
|
||||
else {
|
||||
// the first one is not from us
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sole device handshaking with group
|
||||
state HandshakingToJoin {
|
||||
on Init
|
||||
do showJoinGroupHandshake;
|
||||
|
||||
// Cancel is Rollback
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Rollback {
|
||||
if sameNegotiation
|
||||
go Sole;
|
||||
}
|
||||
|
||||
// Reject is CommitReject
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
|
||||
on CommitAcceptForGroup {
|
||||
if sameNegotiation
|
||||
go HandshakingToJoinPhase2;
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
// Accept is Phase1Commit
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
go HandshakingToJoinPhase1;
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingToJoinPhase1 {
|
||||
on Rollback {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
go Sole;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitAcceptForGroup {
|
||||
if sameNegotiation {
|
||||
send CommitAccept;
|
||||
go JoiningGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingToJoinPhase2 {
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Sole;
|
||||
}
|
||||
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
do disable;
|
||||
go End;
|
||||
}
|
||||
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
send CommitAccept;
|
||||
go JoiningGroup;
|
||||
}
|
||||
}
|
||||
|
||||
state JoiningGroup {
|
||||
on Init {
|
||||
// we need to keep in memory which keys
|
||||
// we have before joining
|
||||
do prepareOwnKeys;
|
||||
do backupOwnKeys;
|
||||
}
|
||||
on GroupKeysForNewMember {
|
||||
if sameNegotiationAndPartner {
|
||||
do saveGroupKeys;
|
||||
do receivedKeysAreDefaultKeys;
|
||||
// send the keys we had before joining
|
||||
do prepareOwnKeysFromBackup;
|
||||
send GroupKeysAndClose;
|
||||
do showDeviceAdded;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingGrouped {
|
||||
on Init
|
||||
do showGroupedHandshake;
|
||||
|
||||
// Cancel is Rollback
|
||||
on Cancel {
|
||||
send Rollback;
|
||||
go Grouped;
|
||||
}
|
||||
|
||||
on Rollback {
|
||||
if sameNegotiation
|
||||
go Grouped;
|
||||
}
|
||||
|
||||
// Reject is CommitReject
|
||||
on Reject {
|
||||
send CommitReject;
|
||||
go Grouped;
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation
|
||||
go Grouped;
|
||||
}
|
||||
|
||||
// Accept is Phase1Commit
|
||||
on Accept {
|
||||
do trustThisKey;
|
||||
go HandshakingGroupedPhase1;
|
||||
}
|
||||
|
||||
on GroupTrustThisKey {
|
||||
if fromGroupMember { // double check
|
||||
do trustThisKey;
|
||||
if sameNegotiation
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
|
||||
on GroupKeysUpdate {
|
||||
if fromGroupMember // double check
|
||||
do saveGroupKeys;
|
||||
}
|
||||
}
|
||||
|
||||
state HandshakingGroupedPhase1 {
|
||||
on Init {
|
||||
send GroupTrustThisKey;
|
||||
send CommitAcceptForGroup;
|
||||
}
|
||||
|
||||
on Rollback {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitReject {
|
||||
if sameNegotiation {
|
||||
do untrustThisKey;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
|
||||
on CommitAccept {
|
||||
if sameNegotiation {
|
||||
do prepareOwnKeys;
|
||||
send GroupKeysForNewMember;
|
||||
do showDeviceAccepted;
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
|
||||
on GroupTrustThisKey {
|
||||
if fromGroupMember // double check
|
||||
do trustThisKey;
|
||||
}
|
||||
|
||||
on GroupKeysUpdate {
|
||||
if fromGroupMember // double check
|
||||
do saveGroupKeys;
|
||||
}
|
||||
|
||||
on GroupKeysAndClose {
|
||||
if fromGroupMember { // double check
|
||||
// do not save GroupKeys as default keys; key data is
|
||||
// already imported
|
||||
go Grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
external Accept 129;
|
||||
external Reject 130;
|
||||
external Cancel 131;
|
||||
|
||||
// beacons are always broadcasted
|
||||
|
||||
message Beacon 2, type=broadcast,
|
||||
ratelimit=10, security=unencrypted {
|
||||
field TID challenge;
|
||||
auto Version version;
|
||||
}
|
||||
|
||||
message NegotiationRequest 3, security=untrusted {
|
||||
field TID challenge;
|
||||
field TID response;
|
||||
auto Version version;
|
||||
field TID negotiation;
|
||||
field bool is_group;
|
||||
}
|
||||
|
||||
message NegotiationOpen 4, security=untrusted {
|
||||
field TID response;
|
||||
auto Version version;
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message Rollback 5, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message CommitReject 6, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message CommitAcceptOfferer 7, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message CommitAcceptRequester 8, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message CommitAccept 9, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
message CommitAcceptForGroup 10, security=untrusted {
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
// default: security=trusted
|
||||
// messages are only accepted when coming from the device group
|
||||
message GroupTrustThisKey 11 {
|
||||
field Hash key;
|
||||
field TID negotiation;
|
||||
}
|
||||
|
||||
// trust in future
|
||||
message GroupKeysForNewMember 12,
|
||||
security=attach_own_keys_for_new_member {
|
||||
field IdentityList ownIdentities;
|
||||
}
|
||||
|
||||
message GroupKeysAndClose 13,
|
||||
security=attach_own_keys_for_group {
|
||||
field IdentityList ownIdentities;
|
||||
}
|
||||
|
||||
message OwnKeysOfferer 14, security=attach_own_keys_for_group {
|
||||
field IdentityList ownIdentities;
|
||||
}
|
||||
|
||||
message OwnKeysRequester 15,
|
||||
security=attach_own_keys_for_new_member {
|
||||
field IdentityList ownIdentities;
|
||||
}
|
||||
|
||||
// grouped handshake
|
||||
message NegotiationRequestGrouped 16, security=untrusted {
|
||||
field TID challenge;
|
||||
field TID response;
|
||||
auto Version version;
|
||||
field TID negotiation;
|
||||
field bool is_group;
|
||||
}
|
||||
|
||||
message GroupHandshake 17 {
|
||||
field TID negotiation;
|
||||
field Hash key;
|
||||
}
|
||||
|
||||
// update group
|
||||
message GroupKeysUpdate 18, security=attach_own_keys_for_group {
|
||||
field IdentityList ownIdentities;
|
||||
}
|
||||
|
||||
// initiate unled group key reset
|
||||
message InitUnledGroupKeyReset 19 {
|
||||
}
|
||||
|
||||
message ElectGroupKeyResetLeader 20 {
|
||||
field TID response;
|
||||
}
|
||||
|
||||
message SynchronizeGroupKeys 21, ratelimit=60 {
|
||||
}
|
||||
|
||||
[...]
|
||||
}
|
||||
|
||||
[...]
|
||||
|
||||
}
|
Loading…
Reference in new issue