<> <> DIRECTORY DESFace USING [ Block, CBCCheckEncrypt, CorrectParity, EncryptBlock, GetRandomIV, GetRandomKey, IV, Key, nullKey ], Names USING [ GetGVDetails, GVDetails, Results ], Rope USING [ Length ], RPC USING [ AuthenticateFailed, ConversationLevel, EncryptionKey, maxPrincipalLength, Principal ], RPCInternal USING [ Authenticator, AuthenticatorObject, ConversationObject ], RPCSecurity USING [ CopyPrincipal, EntryGenerate ] ; NamesGVAuthImpl: CEDAR PROGRAM IMPORTS DESFace, Names, Rope, RPC, RPCSecurity EXPORTS Names, RPC SHARES RPCSecurity = { Conversation: TYPE = REF ConversationObject; ConversationObject: PUBLIC TYPE = RPCInternal.ConversationObject; Authenticator: TYPE = RPCInternal.Authenticator; <> <<{KY}KB, spare, { {CK}KB, spare, time, A }KY .>> <> -- The rest is encrypted with CBC-check using a zero IV -- AuthenticatorLayout: TYPE = MACHINE DEPENDENT RECORD[ ky(0): DESFace.Key, kySpare(4): DESFace.Key, -- space for larger keys! -- ck(8): DESFace.Key, ckSpare(12): DESFace.Key, -- space for larger keys! -- time(16): LONG CARDINAL, a(18): StringBody]; StartConversation: PUBLIC PROC[ caller: RPC.Principal, key: RPC.EncryptionKey, callee: RPC.Principal, level: RPC.ConversationLevel] RETURNS[ conversation: Conversation] = TRUSTED { authenticator: Authenticator; convKey: DESFace.Key; results: Names.Results; details: Names.GVDetails; iv: DESFace.IV; <> nBlks: CARDINAL =( SIZE[AuthenticatorLayout] - SIZE[StringBody[0]] + SIZE[StringBody[caller.Length[]]] + SIZE[DESFace.Block]-1 --rounding-- ) / SIZE[DESFace.Block]; IF caller.Length[] > RPC.maxPrincipalLength THEN ERROR RPC.AuthenticateFailed[badCaller]; IF callee.Length[] > RPC.maxPrincipalLength THEN ERROR RPC.AuthenticateFailed[badCallee]; <> [results, details] _ Names.GetGVDetails[rName: caller, key: key, mode: ok, authenticate: TRUE]; SELECT results FROM error => ERROR RPC.AuthenticateFailed[communications]; notFound => ERROR RPC.AuthenticateFailed[badCaller]; ENDCASE; IF ~details.valid THEN ERROR RPC.AuthenticateFailed[badCaller]; IF ~details.authentic THEN ERROR RPC.AuthenticateFailed[badKey]; [results, details] _ Names.GetGVDetails[rName: callee, mode: ok]; SELECT results FROM error => ERROR RPC.AuthenticateFailed[communications]; notFound => ERROR RPC.AuthenticateFailed[badCallee]; ENDCASE; iv _ DESFace.GetRandomIV[]; authenticator _ NEW[RPCInternal.AuthenticatorObject[nBlks]]; BEGIN kb: DESFace.Key _ DESFace.nullKey -- !!! --; authRec: LONG POINTER TO AuthenticatorLayout = LOOPHOLE[@authenticator[0]]; authRec.ky _ DESFace.GetRandomKey[]; authRec.ck _ convKey _ DESFace.GetRandomKey[]; authRec.time _ 0; RPCSecurity.CopyPrincipal[from: caller, to: @(authRec.a)]; DESFace.CorrectParity[@kb]; DESFace.EncryptBlock[key: kb, from: LOOPHOLE[@authRec.ck], to: LOOPHOLE[@authRec.ck] ]; DESFace.CBCCheckEncrypt[key: authRec.ky, nBlks: nBlks-2, from: LOOPHOLE[@authRec.ck], to: LOOPHOLE[@authRec.ck], seed: [0,0,0,0] ]; DESFace.EncryptBlock[key: kb, from: LOOPHOLE[@authRec.ky], to: LOOPHOLE[@authRec.ky] ]; END; <> RETURN[RPCSecurity.EntryGenerate[level, iv, caller, callee, convKey, authenticator]]; }; }.