Decrypting should work.
authorUmmon <greg.burri@gmail.com>
Thu, 27 Nov 2014 14:18:10 +0000 (15:18 +0100)
committerUmmon <greg.burri@gmail.com>
Thu, 27 Nov 2014 14:18:10 +0000 (15:18 +0100)
labo2-fsharp/CryptoFile/API.fs
labo2-fsharp/CryptoFile/Crypto.fs
labo2-fsharp/CryptoFile/Types.fs
rapport/main.pdf [deleted file]
rapport/main.tex

index e4a7008..0014c1e 100644 (file)
@@ -2,19 +2,24 @@
 open System.IO
 
 type internal Metadata (d: (string * string) list) =
-    new (stream : Stream, size: int) =
-        let binaryReader = new BinaryReader (stream)
-        new Metadata ([])
+    new (stream : Stream) =
+        let reader = new BinaryReader (stream)
+        let length = reader.ReadByte () |> int
+        new Metadata ([for i in 1..length -> reader.ReadString (), reader.ReadString ()])
+
+    // May raise 'KeyNotFoundException'.
+    member this.get (key: string) : string =
+        List.pick (function
+                    | (k, v) when k = key -> Some (v)
+                    | _ -> None) d
 
     member this.WriteTo (stream : Stream) =
-        let memoryStream = new MemoryStream () // To know the serialized meta-data size before writtent them to 'stream'.
-        let memoryWriter = new BinaryWriter (memoryStream)
-        List.iter (fun (key : string, value : string) -> memoryWriter.Write key; memoryWriter.Write value) d
-        (new BinaryWriter (stream)).Write (int memoryStream.Length)
-        memoryStream.CopyTo (stream)
+        let writer = new BinaryWriter (stream)
+        writer.Write (byte d.Length)
+        List.iter (fun (key : string, value : string) -> writer.Write key; writer.Write value) d
 
 module API =
-    module internal MetaData =
+    module internal Metadata =
         let filename = "filename"
         let creationTimeKey = "file-creation-time"
 
@@ -37,8 +42,8 @@ module API =
         let cryptoWriter = new BinaryWriter (cryptoStream)
 
         // Write the file metadata.
-        let metaData = new Metadata ([MetaData.filename, fileInfo.Name
-                                      MetaData.creationTimeKey, fileInfo.CreationTimeUtc.Ticks.ToString ()])
+        let metaData = new Metadata ([Metadata.filename, fileInfo.Name
+                                      Metadata.creationTimeKey, fileInfo.CreationTimeUtc.Ticks.ToString ()])
         metaData.WriteTo cryptoStream
 
         // Write the content of the file.
@@ -54,4 +59,31 @@ module API =
         ()
 
     let decryptFile (sourceFilePath : string) (targetDirPath : string) (signaturePubKey: Key) (decryptPrivKey : Key) =
-        ()
\ No newline at end of file
+        use inputStream = new FileStream (sourceFilePath, FileMode.Open, FileAccess.Read)
+        use reader = new BinaryReader (inputStream)
+        let mac = reader.ReadBytes 32
+        let signature = reader.ReadBytes 256
+        let keys = reader.ReadBytes 256 |> Crypto.decryptRSA decryptPrivKey
+        let keyAES = keys.[0..31]
+        let keyMAC = keys.[32..63]
+        let iv = keys.[64..79]
+
+        // Integrity validation.
+        let mac' = Crypto.ComputeHMAC keyMAC inputStream
+        if mac' <> mac then
+            raise IntegrityError
+
+        // Authentication validation.
+        if not <| Crypto.verifySignRSA signaturePubKey mac' signature then
+            raise SignatureMismatch
+
+        // Decrypt metadata.
+        inputStream.Position <- 32L + 256L + 256L
+        use cryptoStream = Crypto.decryptAES keyAES iv inputStream
+        let metadata = new Metadata (cryptoStream)
+
+        // Create the file and write.
+        let filename = metadata.get Metadata.filename
+        use outputStream = new FileStream (Path.Combine (targetDirPath, filename), FileMode.Create, FileAccess.Write)
+        cryptoStream.CopyTo outputStream
+        ()
index 21b168e..60f9c5f 100644 (file)
@@ -79,4 +79,9 @@ module internal Crypto =
     let HMACStream (key: byte[]) (outputStream: Stream) : Stream * HMACSHA256 = 
         assert (key.Length = 32)
         let hmac = new HMACSHA256 (key)
-        new CryptoStream (outputStream, hmac, CryptoStreamMode.Write) :> Stream, hmac
\ No newline at end of file
+        new CryptoStream (outputStream, hmac, CryptoStreamMode.Write) :> Stream, hmac
+
+    let ComputeHMAC (key: byte[]) (inputStream: Stream) : byte[] =
+        assert (key.Length = 32)
+        let hmac = new HMACSHA256 (key)
+        hmac.ComputeHash inputStream
\ No newline at end of file
index 67ccbc3..fe72c06 100644 (file)
@@ -1,8 +1,8 @@
 namespace CryptoFile
 
-type Key = string
+type Key = string // For public and private RSA keys.
 
 exception FileNotFound
 exception IOError
-exception SignatureMismatch
 exception IntegrityError
+exception SignatureMismatch
diff --git a/rapport/main.pdf b/rapport/main.pdf
deleted file mode 100644 (file)
index e097785..0000000
Binary files a/rapport/main.pdf and /dev/null differ
index 7e2c280..03a7642 100644 (file)
@@ -66,7 +66,7 @@ ciphertext = AES(plaintext) ;
 plaintext = meta-data, file-content ;
 meta-data = meta-data-size[int32], { key-value-pair } ;
 key-value-pair = key[string], value[string] ;
-string = size[8], content-utf8 ;
+string = size[vint], content-utf8 ;
 \end{lstlisting}
 
 \texttt{meta-data-size} permet de connaître la taille des méta-données afin de les déchiffrer au préalable du contenu du fichier.
@@ -75,6 +75,8 @@ string = size[8], content-utf8 ;
 
 Les méta-données (\texttt{meta-data}) peuvent contenir, par exemple, le nom du fichier, sa date de création, ses droits, ou tout autres données associées.
 
+Le type \texttt{vint} correspond à un entier de taille variable, initialement occupant un octets.
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{processus}
@@ -84,10 +86,9 @@ Les méta-données (\texttt{meta-data}) peuvent contenir, par exemple, le nom du
 Entrées :
 
 \begin{itemize}
-   \item $f$ : contenu du fichier
-   \item $metas$ : métas données associées au fichier
+   \item $f$ : fichier
    \item $k_{pub}$ : clef publique RSA
-   \item $k_{signpriv}$ : clef privé de signature DSA
+   \item $k_{signpriv}$ : clef privé de signature RSA
 \end{itemize}
 
 
@@ -108,9 +109,27 @@ Processus :
 Où $+$ dénote la concaténation.
 
 
-
 \subsection{déchiffrement}
 
+Entrée :
+
+\begin{itemize}
+   \item $c$ : container chiffrées
+   \item $k_{priv}$ : clef privée RSA
+   \item $k_{signpub}$ : la clef publique de signature RSA
+\end{itemize}
+
+Processus :
+
+\begin{enumerate}
+   \item Lecture de $mac$, calcul de $mac'$ sur $c$ comparaison des deux afin de vérifier l'intégrité.
+   \item Vérification de la signature avec $k_{signpub}$.
+   \item Déchiffrement de $k_c + k_a + iv$ avec $k_{priv}$.
+   \item Déchiffrement du reste des données ($ciphertext$).
+\end{enumerate}
+
+Ce processus nécessite deux cycles de lecture des données, le premier pour le calcul de $mac'$ et le deuxième pour le déchiffrement. Le deuxième cycle n'est effectué que si l'intégrité et l'authenticité ont été validés.
+
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Implémentation}
@@ -159,7 +178,6 @@ Concerne les clefs externes à l'\emph{API}.
 \end{itemize}
 
 
-
 \subsubsection{Clefs internes}
 
 Concerne les clefs gérer à l'intérieur du container.