<> <> <> <> << >> <<>> DIRECTORY FS USING [StreamOpen, Error, Copy], IO USING [STREAM, EndOfStream, GetLineRope, PutRope, Close], MessageWindow USING [Append, Blink], BigCardinals USING [BigCARD, BigToDecimalRope, BigFromDecimalRope, BigToRope, BigFromRope], EncryptionKeys USING [ToLowerCase], Rope USING [ROPE, Concat, Cat], RSA USING [KeyGenerate, Decrypt]; <<>> MasterKeyImpl: CEDAR PROGRAM IMPORTS EncryptionKeys, FS, IO, RSA, BigCardinals, Rope, MessageWindow = BEGIN KeyFail: PUBLIC ERROR [subclass: ATOM _ $Unspecified] = CODE; MasterKeyCreate: PUBLIC PROC[] ~ { length: CARDINAL _ 30; public, private: BigCardinals.BigCARD; PublicFile, PrivateFile: IO.STREAM; BEGIN [public, private] _ RSA.KeyGenerate[length]; PrivateFile _ FS.StreamOpen["///Keys/MASTER.PrivateKey", $create !FS.Error => IF error.group = user THEN GOTO CannotOpenPrivate;]; IO.PutRope[PrivateFile, Rope.Concat[BigCardinals.BigToDecimalRope[private], "\n"]]; PrivateFile.Close[]; PublicFile _ FS.StreamOpen["///Keys/MASTER.PublicKey", $create !FS.Error => IF error.group = user THEN GOTO CannotOpenPublic;]; IO.PutRope[PublicFile, Rope.Concat[BigCardinals.BigToDecimalRope[public], "\n"]]; PublicFile.Close[]; []_FS.Copy["///Keys/MASTER.PublicKey", "[Indigo]Keys>MASTER.PublicKey" !FS.Error => GOTO CannotCopy]; EXITS CannotOpenPrivate => { MessageWindow.Append[Rope.Concat["Cannot Open ///Keys/MASTER.PrivateKey"], TRUE]; MessageWindow.Blink; ERROR KeyFail[$CannotOpenPrivate]; }; CannotOpenPublic => { MessageWindow.Append[Rope.Concat["Cannot Open [Indigo]Keys>MASTER.PublicKey"], TRUE]; MessageWindow.Blink; ERROR KeyFail[$CannotOpenPublic]; }; CannotCopy => { MessageWindow.Append["Cannot copy public key into [Indigo]Keys>MASTER.PublicKey", TRUE]; MessageWindow.Blink; ERROR KeyFail[$CannotCopy]; }; END; }; SignPublicKey: PUBLIC PROC[user: Rope.ROPE] ~ { RemotePublicFileName, LocalPublicFileName, lCaseUser: Rope.ROPE; PublicFile, masterPrivateFile, masterPublicFile: IO.STREAM; masterPublicKey, masterPrivateKey, publicKey, publicSignedByMaster: BigCardinals.BigCARD; BEGIN lCaseUser _ EncryptionKeys.ToLowerCase[user]; RemotePublicFileName _ Rope.Cat["[Indigo]Keys>", lCaseUser, ".PublicKey"]; LocalPublicFileName _ Rope.Cat["///Temp/", lCaseUser, ".PublicKey"]; []_FS.Copy[RemotePublicFileName, LocalPublicFileName !FS.Error => GOTO CannotCopy]; PublicFile _ FS.StreamOpen[LocalPublicFileName, $write !FS.Error => IF error.group = user THEN GOTO KeyNotFound;]; publicKey _ BigCardinals.BigFromDecimalRope[IO.GetLineRope[PublicFile !IO.EndOfStream => GOTO NoPublicKey]]; masterPrivateFile _ FS.StreamOpen["///Keys/MASTER.PrivateKey" !FS.Error => IF error.group = user THEN GOTO MasterPrivateMissing]; masterPrivateKey _ BigCardinals.BigFromDecimalRope[IO.GetLineRope[masterPrivateFile ! IO.EndOfStream => GOTO MasterPrivateMissing]]; masterPrivateFile.Close[]; masterPublicFile _ FS.StreamOpen["///Keys/MASTER.PublicKey" !FS.Error => IF error.group = user THEN GOTO MasterPublicMissing]; masterPublicKey _ BigCardinals.BigFromDecimalRope[IO.GetLineRope[masterPublicFile ! IO.EndOfStream => GOTO MasterPublicMissing]]; masterPublicFile.Close[]; publicSignedByMaster _ RSA.Decrypt[BigCardinals.BigFromRope[Rope.Concat[lCaseUser, BigCardinals.BigToRope[publicKey]]], masterPublicKey, masterPrivateKey]; IO.PutRope[PublicFile, Rope.Concat[BigCardinals.BigToDecimalRope[publicSignedByMaster], "\n"]]; PublicFile.Close[]; []_FS.Copy[LocalPublicFileName, RemotePublicFileName !FS.Error => GOTO CannotCopy]; EXITS KeyNotFound => { MessageWindow.Append[Rope.Concat["Cannot Open ", LocalPublicFileName], TRUE]; MessageWindow.Blink; ERROR KeyFail[$PublicKeyNotFound]; }; NoPublicKey => { MessageWindow.Append[Rope.Concat[LocalPublicFileName, "Empty"], TRUE]; MessageWindow.Blink; ERROR KeyFail[$PublicKeyEmpty]; }; MasterPrivateMissing => { MessageWindow.Append[Rope.Concat["///Keys/MASTER.PrivateKey is missing form local disk"], TRUE]; MessageWindow.Blink; ERROR KeyFail[$MasterPrivateNotFound]; }; MasterPublicMissing => { MessageWindow.Append[Rope.Concat["///Keys/MASTER.PublicKey is missing form local disk"], TRUE]; MessageWindow.Blink; ERROR KeyFail[$MasterPublicNotFound]; }; CannotCopy => { MessageWindow.Append["Cannot Copy Users Public File", TRUE]; MessageWindow.Blink; ERROR KeyFail[$CannotCopyPublicKey]; }; END; }; END.