Skip to content

Commit b86509f

Browse files
committed
Merge branch 'master' into ep/conc-msgs
2 parents a0c94ec + 39eb3c4 commit b86509f

2 files changed

Lines changed: 75 additions & 9 deletions

File tree

src/Simplex/Messaging/Agent/Protocol.hs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ module Simplex.Messaging.Agent.Protocol
122122
OwnerId,
123123
ConnectionLink (..),
124124
AConnectionLink (..),
125+
SimplexNameInfo (..),
126+
SimplexTLD (..),
127+
SimplexNameType (..),
125128
ConnShortLink (..),
126129
AConnShortLink (..),
127130
CreatedConnLink (..),
@@ -138,6 +141,8 @@ module Simplex.Messaging.Agent.Protocol
138141
connReqUriP',
139142
simplexConnReqUri,
140143
simplexShortLink,
144+
fullDomainName,
145+
shortNameInfoStr,
141146
AgentErrorType (..),
142147
CommandErrorType (..),
143148
ConnectionErrorType (..),
@@ -189,10 +194,11 @@ import qualified Data.Aeson.TH as J
189194
import qualified Data.Aeson.Types as JT
190195
import Data.Attoparsec.ByteString.Char8 (Parser)
191196
import qualified Data.Attoparsec.ByteString.Char8 as A
197+
import qualified Data.Attoparsec.Text as AT
192198
import qualified Data.ByteString.Base64.URL as B64
193199
import Data.ByteString.Char8 (ByteString)
194200
import qualified Data.ByteString.Char8 as B
195-
import Data.Char (toLower, toUpper)
201+
import Data.Char (isAlpha, isDigit, toLower, toUpper)
196202
import Data.Foldable (find)
197203
import Data.Functor (($>))
198204
import Data.Int (Int64)
@@ -1524,6 +1530,61 @@ instance (Typeable c, ConnectionModeI c) => FromField (ConnShortLink c) where fr
15241530

15251531
data ContactConnType = CCTContact | CCTChannel | CCTGroup | CCTRelay deriving (Eq, Show)
15261532

1533+
data SimplexNameInfo = SimplexNameInfo
1534+
{ nameType :: SimplexNameType,
1535+
nameTLD :: SimplexTLD,
1536+
domain :: Text,
1537+
subDomain :: [Text] -- parent to child: ["b", "a"] for a.b.domain.simplex
1538+
}
1539+
deriving (Eq, Show)
1540+
1541+
data SimplexTLD = TLDSimplex | TLDTesting | TLDWeb
1542+
deriving (Eq, Show)
1543+
1544+
data SimplexNameType = NTPublicGroup | NTContact
1545+
deriving (Eq, Show)
1546+
1547+
instance StrEncoding SimplexNameType where
1548+
strEncode = \case
1549+
NTPublicGroup -> "#"
1550+
NTContact -> "@"
1551+
strP = A.char '#' $> NTPublicGroup <|> A.char '@' $> NTContact
1552+
1553+
instance StrEncoding SimplexNameInfo where
1554+
strEncode info = "simplex:/name" <> strEncode (nameType info) <> encodeUtf8 (fullDomainName info)
1555+
strP = optional "simplex:/name" *> (strP >>= nameP) <|> nameP NTPublicGroup
1556+
where
1557+
nameP nt = parseName nt . safeDecodeUtf8 <$?> A.takeWhile1 (not . A.isSpace)
1558+
parseName nt s = AT.parseOnly (nameLabelP `AT.sepBy1` AT.char '.' <* AT.endOfInput) s >>= mkNameInfo nt
1559+
nameLabelP = T.intercalate "-" <$> AT.takeWhile1 (\c -> isNameLetter c || isDigit c) `AT.sepBy1` AT.char '-'
1560+
isNameLetter c = isAlpha c && not (c >= '\x00c0' && c <= '\x024f')
1561+
mkNameInfo nt labels = case reverse labels of
1562+
[] -> Left "empty name"
1563+
[name]
1564+
| nt == NTPublicGroup -> Right $ SimplexNameInfo nt TLDSimplex name []
1565+
| otherwise -> Left "contact name requires TLD"
1566+
tld : name : sub -> Right $ case tld of
1567+
"simplex" -> SimplexNameInfo nt TLDSimplex name sub
1568+
"testing" -> SimplexNameInfo nt TLDTesting name sub
1569+
_ -> SimplexNameInfo nt TLDWeb (T.intercalate "." labels) []
1570+
1571+
fullDomainName :: SimplexNameInfo -> Text
1572+
fullDomainName SimplexNameInfo {nameTLD, domain, subDomain} = T.intercalate "." (reverse subDomain ++ [domain] ++ tld')
1573+
where
1574+
tld' = case nameTLD of
1575+
TLDSimplex -> ["simplex"]
1576+
TLDTesting -> ["testing"]
1577+
TLDWeb -> []
1578+
1579+
shortNameInfoStr :: SimplexNameInfo -> Text
1580+
shortNameInfoStr = \case
1581+
SimplexNameInfo {nameType = NTPublicGroup, nameTLD = TLDSimplex, domain, subDomain = []} -> "#" <> domain
1582+
info -> pfx <> fullDomainName info
1583+
where
1584+
pfx = case nameType info of
1585+
NTPublicGroup -> "#"
1586+
NTContact -> "@"
1587+
15271588
data AConnShortLink = forall m. ConnectionModeI m => ACSL (SConnectionMode m) (ConnShortLink m)
15281589

15291590
instance Eq AConnShortLink where
@@ -2201,3 +2262,9 @@ instance FromJSON ACreatedConnLink where
22012262
instance ToJSON ACreatedConnLink where
22022263
toEncoding (ACCL _ ccLink) = toEncoding ccLink
22032264
toJSON (ACCL _ ccLink) = toJSON ccLink
2265+
2266+
$(J.deriveJSON (enumJSON $ dropPrefix "TLD") ''SimplexTLD)
2267+
2268+
$(J.deriveJSON (enumJSON $ dropPrefix "NT") ''SimplexNameType)
2269+
2270+
$(J.deriveJSON defaultJSON ''SimplexNameInfo)

src/Simplex/Messaging/Transport.hs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -824,23 +824,22 @@ smpClientHandshake c ks_ keyHash@(C.KeyHash kh) vRange proxyServer serviceKeys_
824824
serverKey <- getServerVerifyKey c
825825
(,certKey) <$> (C.x509ToPublic' =<< C.verifyX509 serverKey exact)
826826
let v = maxVersion vr
827+
serviceVersion ServiceCredentials {serviceRole} = if serviceRole == SRMessaging then rcvServiceSMPVersion else serviceCertsSMPVersion
827828
serviceKeys = case serviceKeys_ of
828-
Just sks | v >= serviceCertsSMPVersion && certificateSent c -> Just sks
829+
Just sks | v >= serviceVersion (fst sks) && certificateSent c -> Just sks
829830
_ -> Nothing
830-
clientService = mkClientService v =<< serviceKeys
831+
clientService = mkClientService <$> serviceKeys
831832
hs = SMPClientHandshake {smpVersion = v, keyHash, authPubKey = fst <$> ks_, proxyServer, clientService}
832833
sendHandshake th hs
833834
service <- mapM getClientService serviceKeys
834835
liftIO $ smpTHandleClient th v vr (snd <$> ks_) ck_ proxyServer service
835836
Nothing -> throwE TEVersion
836837
where
837838
th@THandle {params = THandleParams {sessionId}} = smpTHandle c
838-
mkClientService :: VersionSMP -> (ServiceCredentials, C.KeyPairEd25519) -> Maybe SMPClientHandshakeService
839-
mkClientService v (ServiceCredentials {serviceRole, serviceCreds, serviceSignKey}, (k, _))
840-
| serviceRole == SRMessaging && v < rcvServiceSMPVersion = Nothing
841-
| otherwise =
842-
let sk = C.signX509 serviceSignKey $ C.publicToX509 k
843-
in Just SMPClientHandshakeService {serviceRole, serviceCertKey = CertChainPubKey (fst serviceCreds) sk}
839+
mkClientService :: (ServiceCredentials, C.KeyPairEd25519) -> SMPClientHandshakeService
840+
mkClientService (ServiceCredentials {serviceRole, serviceCreds, serviceSignKey}, (k, _)) =
841+
let sk = C.signX509 serviceSignKey $ C.publicToX509 k
842+
in SMPClientHandshakeService {serviceRole, serviceCertKey = CertChainPubKey (fst serviceCreds) sk}
844843
getClientService :: (ServiceCredentials, C.KeyPairEd25519) -> ExceptT TransportError IO THClientService
845844
getClientService (ServiceCredentials {serviceRole, serviceCertHash}, (_, pk)) =
846845
getHandshake th >>= \case

0 commit comments

Comments
 (0)