tp4
This commit is contained in:
parent
52a7aa407f
commit
af22899fa8
@ -16,4 +16,8 @@ Cryptographie - Outils et algorithmes
|
|||||||
- cm : [Algorithmes à clefs publiques](cours/crypto.pdf).
|
- cm : [Algorithmes à clefs publiques](cours/crypto.pdf).
|
||||||
- tp : [Diffie-Hellman](td_tp/tp3)
|
- tp : [Diffie-Hellman](td_tp/tp3)
|
||||||
|
|
||||||
|
#### Semaine 4
|
||||||
|
- cm : [Signatures, certificats](cours/crypto.pdf).
|
||||||
|
- tp : [OpenSSL (chiffrements, hashages, signatures, certificats)](td_tp/tp4)
|
||||||
|
|
||||||
|
|
||||||
|
BIN
td_tp/tp4/M1.ps.gz
Normal file
BIN
td_tp/tp4/M1.ps.gz
Normal file
Binary file not shown.
BIN
td_tp/tp4/M2.ps.gz
Normal file
BIN
td_tp/tp4/M2.ps.gz
Normal file
Binary file not shown.
444
td_tp/tp4/README.md
Normal file
444
td_tp/tp4/README.md
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
# TP4
|
||||||
|
|
||||||
|
> Dans ce tp, on utilise la boîte à outils **openssl** pour :
|
||||||
|
>
|
||||||
|
> - Chiffrage/déchiffrage (symétriques et à clés publiques).
|
||||||
|
> - Hashage.
|
||||||
|
> - Signature.
|
||||||
|
> - Création/utilisation de certificats.
|
||||||
|
|
||||||
|
### OpenSSL
|
||||||
|
<details><summary>Openssl</summary>
|
||||||
|
<div>
|
||||||
|
Vous pouvez utiliser les fonctionnalités suivantes :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl genrsa -out fichier_rsa.priv size
|
||||||
|
```
|
||||||
|
|
||||||
|
génére la clé privé RSA de taille size. les valeurs possible pour size
|
||||||
|
sont : 512, 1024, etc.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsa -in fichier_rsa.priv -des3 -out fichier.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
chiffre la clef privé RSA avec l'algorithme DES3. Vous pouvez utiliser DES, 3DES, IDEA,etc.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsa -in fichier_rsa.priv -pubout -out fichier_rsa.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
stocke la partie publique dans un fichier à part (création de de la clé
|
||||||
|
publique associée à la clef privée dans le fichier fichier.pem).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl enc -algo -in claire.txt -out chiffre.enc
|
||||||
|
```
|
||||||
|
|
||||||
|
pour le chiffrement de claire.txt avec l'algorithme spécifié (`openssl enc --help` pour avoir la liste des possibilités ou bien openssl
|
||||||
|
list-cipher-commands) dans un fichier chiffre.enc.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl enc -algo -in chiffre -d -out claire
|
||||||
|
```
|
||||||
|
|
||||||
|
pour le déchiffrement.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl dgst -algo -out sortie entrée
|
||||||
|
```
|
||||||
|
|
||||||
|
pour hacher un fichier. L'option -algo est le choix de l'algorithme de
|
||||||
|
hachage (sha, sha1, dss1, md2,md4, md5, ripemd160).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rand -out clé.key nombre_bits
|
||||||
|
```
|
||||||
|
|
||||||
|
pour générer un nombre aléatoire de taille nombre_bits (utiliser
|
||||||
|
l'option -base 64 pour la lisibilité).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl aes-256-cbc -in claire.txt -out chiffre.enc -e -k clé.key
|
||||||
|
```
|
||||||
|
|
||||||
|
pour chiffrer un fichier avec l'AES.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsautl -encrypt -inkey rsa.pub -in clair.txt -out chiffre.enc
|
||||||
|
```
|
||||||
|
|
||||||
|
chiffrer fichier.txt avec la RSA en utilisant la clef publique rsa.pub.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsautl -decrypt -inkey rsa.priv -in chiffre.enc -out fihcier.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
pour déchiffrer le fichier fic.dec.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsautl -sign -inkey ras.priv -in fichier.txt -out fic.sig
|
||||||
|
```
|
||||||
|
|
||||||
|
pour générer une signature.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsautl -verify -pubin -inkey rsa.pub -in fic.sig
|
||||||
|
```
|
||||||
|
|
||||||
|
pour vérifier une signature.
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Chiffrage symétrique
|
||||||
|
|
||||||
|
#### Avec mot de passe
|
||||||
|
|
||||||
|
La liste des algorithme de chiffrement symétrique est donnée par la
|
||||||
|
commande
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl enc -ciphers
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour chiffrer le fichier toto avec le système Blowfish en mode CBC, avec
|
||||||
|
une clé générée par mot de passe, le chiffré étant stocké dans le
|
||||||
|
fichier toto.chiffre , on utilise la commande :
|
||||||
|
|
||||||
|
openssl enc -bf-cbc -in toto -out toto.chiffre
|
||||||
|
|
||||||
|
Pour déchiffrer le même message, on utilise la commande :
|
||||||
|
|
||||||
|
openssl enc -bf-cbc -d -in toto.chiffre -out toto.dechiffre
|
||||||
|
|
||||||
|
**Exercice 1**
|
||||||
|
|
||||||
|
- Chiffrer et déchiffrer un fichier de votre choix. Vérifier avec la
|
||||||
|
commande `diff`.
|
||||||
|
- Comment expliquer la différence de taille du fichier et du fichier
|
||||||
|
chiffré ?
|
||||||
|
- Que se passe-t-il si le mot de passe est invalide ?
|
||||||
|
|
||||||
|
**Exercice 2**
|
||||||
|
|
||||||
|
Le cryptogramme [cryptogramme](./cryptogramme) a été chiffré avec AES en
|
||||||
|
mode CBC, la clé de 128 bits ayant été obtenue par mot de passe. Sachant
|
||||||
|
le codage en base 64 du mot de passe est `VHN1bmFtaQo=`, déchiffrez le
|
||||||
|
cryptogramme.
|
||||||
|
|
||||||
|
#### Avec clé explicite (mode CBC)
|
||||||
|
|
||||||
|
Pour chiffrer le fichier toto avec une clé explicite, il faut utiliser
|
||||||
|
les options -K (ou -kfile) et -iv
|
||||||
|
|
||||||
|
- `-K` ( K majuscule) suivi de la clé exprimée en hexadécimal ;
|
||||||
|
- `-iv` ( iv en minuscules) suivi du vecteur d'initialisation exprimé
|
||||||
|
en hexadécimal.
|
||||||
|
|
||||||
|
L'exemple qui suit montre la commande pour chiffrer toto avec Blowfish
|
||||||
|
en mode CBC avec un vecteur d'initialisation de 64 bits, et une clé de
|
||||||
|
128 bits :
|
||||||
|
|
||||||
|
openssl enc -bf-cbc -in toto -out toto.chiffre \
|
||||||
|
-iv 0123456789ABCDEF \
|
||||||
|
-K 0123456789ABCDEF0123456789ABCDEF
|
||||||
|
|
||||||
|
**Exercice 3**
|
||||||
|
|
||||||
|
Générez une clé pour aes-256, ainsi qu'un vecteur d'initialisation
|
||||||
|
(128 bits). Chiffrez et déchiffrez (AES 256 en mode CBC) le fichier
|
||||||
|
clair correspondant au cryptogramme de la question précédente.
|
||||||
|
|
||||||
|
### Chiffrage à clé publique
|
||||||
|
|
||||||
|
On peut générer des clés RSA avec la commande
|
||||||
|
|
||||||
|
openssl genrsa -out keyfile size
|
||||||
|
|
||||||
|
**Exercice 4**
|
||||||
|
|
||||||
|
Générez une clé RSA sur 2048 bits dans le fichier key.pem. Que donne
|
||||||
|
`cat key.pem.`
|
||||||
|
|
||||||
|
openssl rsa -in keyfile -text -noout
|
||||||
|
|
||||||
|
permet de visualiser vos clés
|
||||||
|
|
||||||
|
**Exercice 5**
|
||||||
|
|
||||||
|
- Exportez la partie publique de votre clé dans key.pub.Regardez le
|
||||||
|
fichier.
|
||||||
|
- Chiffrez la clé privée avec idea et un mot de passe. Regardez ce que
|
||||||
|
contient le fichier.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rsa -in maCle.pem -idea -out maCle.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
- Chiffrez "un petit fichier". Quelle est la taille du fichier
|
||||||
|
chiffré ? Déchiffrez-le.
|
||||||
|
- Que se passe-t-il pour un gros fichier ? pourquoi ?
|
||||||
|
|
||||||
|
**Exercice 6**
|
||||||
|
|
||||||
|
Envoyez votre clé publique à un camarade. Celui-ci vous enverra la sienne.
|
||||||
|
Générer un petit fichier texte et envoyez-le à votre voisin chiffré avec
|
||||||
|
sa clef publique. Lui vous enverra un fichier chiffré avec sa clef.
|
||||||
|
Renvoyez-lui le message qu'il vous a envoyé mais en clair.
|
||||||
|
|
||||||
|
**Exercice 7**
|
||||||
|
|
||||||
|
Toujours en binome : A génére une clef AES 256 qu'il chiffre avec la
|
||||||
|
clef publique RSA de B et il lui envoye le chiffré. A partir de là, B
|
||||||
|
récupère la clef (en clair), et il chiffre un gros fichier avec l'AES et
|
||||||
|
la clef AES. Il envoie le gros fichier chiffré à A qui doit le
|
||||||
|
déchiffré.
|
||||||
|
|
||||||
|
### Hachage et mots de passe
|
||||||
|
|
||||||
|
Pour calculer un hachage, utiliez la commande
|
||||||
|
|
||||||
|
openssl dgst -algo -out hash fichier
|
||||||
|
**Exercice 8**
|
||||||
|
|
||||||
|
1. Visitez les possibilités de la commande prime d’OPENSSL.
|
||||||
|
2. Testez la primalité d’un nombre donné : en plus de la réponse, constatez que l'écho de ce nombre
|
||||||
|
a lieu en hexadécimal.
|
||||||
|
3. Testez la primalité d’un nombre passé directement en hexadécimal.
|
||||||
|
4. (facultatif) Ecrivez un petit shell-script UNIX de façon à faire afficher les nombres premiers d'un
|
||||||
|
intervalle donné (utilisez seq ou autre).
|
||||||
|
|
||||||
|
**Exercice 9**
|
||||||
|
|
||||||
|
1. À l'aide de la commande dgst, obtenir dans bash.hash, le hachage du
|
||||||
|
fichier exécutable `/usr/bin/bash`, en choisissant SHA256 (Secure
|
||||||
|
Hash Algorithm) comme algorithme de hashage. Refaire pour obtenir la
|
||||||
|
version binaire du hash dans le fichier executable.hash.bin.
|
||||||
|
Comparer la taille de `/usr/bin/bash`, de executable.hash et de
|
||||||
|
executable.hash.bin. Quelle est la longueur du hash en nombre de
|
||||||
|
bits ? On recommence avec un fichier court oof. Quelle est la
|
||||||
|
longueur du hash en nombre de bits ?
|
||||||
|
2. Changer un seul **bit** dans oof. Comment change le hash ?
|
||||||
|
|
||||||
|
3. On recommence avec MD5 (Digest Message) comme algorithme de hashage.
|
||||||
|
Quelle est la longueur des hashs en nombre de bits.
|
||||||
|
|
||||||
|
4. Récupérez les fichiers [fichier1](./M1.ps.gz) et
|
||||||
|
[fichier2](./M2.ps.gz). Décompressez-les, et regardez leur contenu.
|
||||||
|
5. Calculer leur empreinte MD5 avec `openssl`. Conclusion ?
|
||||||
|
|
||||||
|
6. Même question avec SHA-1 et SHA256.
|
||||||
|
7. S'il s'agit tout simplement de calculer des hashs, on peut utiliser
|
||||||
|
directement certaines commandes, sans passer par openssl. Par
|
||||||
|
exemple les commandes md5sum ou shasum. C'est le cas, par exemple,
|
||||||
|
lorsqu'on télécharge des packages dont on veut vérifier l'intégrité
|
||||||
|
de la copie (à condition bien sûr que le site officiel de l'éditeur
|
||||||
|
du package publie le hash du package).
|
||||||
|
|
||||||
|
**Exercice 10**
|
||||||
|
|
||||||
|
Vous vous retrouvez en possession du hachage MD5 d'un mot de passe que
|
||||||
|
vous voulez casser.
|
||||||
|
|
||||||
|
dde2790ce930e3d425305c36afd4e69c
|
||||||
|
|
||||||
|
Ecrivez un programme force brute qui teste tous les mots d'un
|
||||||
|
dictionnaire. Pour calculer le hachage MD5 d'une chaîne, utilisez la
|
||||||
|
fonction MD5 de openssl (-lcrypto à la compilation)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
unsigned char *MD5(const unsigned char *d, unsigned long n,
|
||||||
|
unsigned char *md);
|
||||||
|
```
|
||||||
|
|
||||||
|
Testez avec le dictionnaire [cracklib-small](./cracklib-small.gz)
|
||||||
|
|
||||||
|
**Exercice 11**
|
||||||
|
|
||||||
|
Vous avez réussi à récupérer le fichier `/etc/shadow` d'un serveur avec
|
||||||
|
la ligne suivante
|
||||||
|
|
||||||
|
toto:$6$oAwY6QyT$WALN/YdWiU16lh19DqFHgLYYj77Grn3L88L8vX8IkgXQJyxH1r4L9/2zjY1fdM81Sx/cv821MXfPHbP.nvR2W.:16680:0:99999:7:::
|
||||||
|
|
||||||
|
Retrouvez le mot de passe du compte toto en procédant comme à
|
||||||
|
l'exercice précédent (utliser la fonction `crypt`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <crypt.h>
|
||||||
|
char *crypt(const char *key, const char *salt);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Signature
|
||||||
|
|
||||||
|
Pour signer un "document", on calcule d'abord une empreinte de ce
|
||||||
|
document. La commande **dgst** permet de le faire.
|
||||||
|
|
||||||
|
openssl dgst -algo -out hash fichier
|
||||||
|
|
||||||
|
Signer un document revient à signer son empreinte. Pour cela, on utilise
|
||||||
|
l'option `-sign` de la commande **rsautl**.
|
||||||
|
|
||||||
|
openssl rsautl -sign -in hash -inkey cle -out signature
|
||||||
|
|
||||||
|
et pour vérifier
|
||||||
|
|
||||||
|
openssl rsautl -verify -in signature -pubin -inkey cle -out hash
|
||||||
|
|
||||||
|
**Exercice 12**
|
||||||
|
|
||||||
|
Le fichier [signatures.tar.gz](./signatures.tar.gz) contient deux
|
||||||
|
fichiers accompagnés d'une signature, ainsi que la clé publique de la
|
||||||
|
clé RSA ayant produit la signature. De ces deux fichiers, lequels a bien
|
||||||
|
été signé.
|
||||||
|
|
||||||
|
**Exercice 13**
|
||||||
|
|
||||||
|
Reprenez le binôme de la partie RSA. Envoyez à votre binôme le fichier
|
||||||
|
/etc/passwd et une signature, qui la vérifiera.
|
||||||
|
|
||||||
|
### Certificats
|
||||||
|
|
||||||
|
#### Création d'une autorité de certification (permettant de signer les demandes de certificats)
|
||||||
|
|
||||||
|
Vous allez jouer le role d'une autorité de certification.
|
||||||
|
|
||||||
|
Par défaut, OpenSSL utilise le fichier de configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
/etc/ssl/openssl.cnf
|
||||||
|
```
|
||||||
|
|
||||||
|
pour la génération des certificats. Pour utiliser un fichier de
|
||||||
|
configuration personnalisé, il suffit d'ajouter l'argument "-config
|
||||||
|
{fichier_de_configuration_personnalisé}" à la commande openssl.
|
||||||
|
Avant de pouvoir générer un certificat , il faut obligatoirement générer
|
||||||
|
une clé RSA ou DSA. Générez une clé RSA `mykey.pem` pour l'autorité de
|
||||||
|
certification chiffrée avec idea.
|
||||||
|
|
||||||
|
Pour générer ses propres certificats, sans passer par une autorité de
|
||||||
|
certification externe :
|
||||||
|
|
||||||
|
openssl req -new -x509 -key mykey.pem -out ca.crt -days 1095
|
||||||
|
|
||||||
|
On indique pour le paramètre `-out` le nom de l'autorité de
|
||||||
|
certification à générer puis la durée de validité en jour avec le
|
||||||
|
paramètre `-days` Cette autorité de certification permettra de signer
|
||||||
|
les futures demandes de certificats auto-signés. Cette génération est à
|
||||||
|
faire une seule fois. Le Common Name à indiquer ne doit correspondre à
|
||||||
|
aucun nom de domaine ayant besoin d'un certificat. Cette autorité de
|
||||||
|
certification peut-être mis à disposition du public afin d'être intégré
|
||||||
|
dans les différents navigateurs comme étant une autorité de
|
||||||
|
certification reconnue.
|
||||||
|
|
||||||
|
#### Création d'une requête de certificat
|
||||||
|
|
||||||
|
Vous allez jouer le role de quelqu'un qui veut obtenir un certificat
|
||||||
|
pour sa clé RSA. Générez une clé RSA dans mykey.pem.
|
||||||
|
|
||||||
|
**Exercice 14**
|
||||||
|
|
||||||
|
Générez une requête de demande de certificat pour votre clé.
|
||||||
|
|
||||||
|
openssl req -new -key maCle.pem -out maRequete.pem
|
||||||
|
|
||||||
|
Consulez cette requête avec
|
||||||
|
|
||||||
|
openssl req -in maRequete.pem -text -noout
|
||||||
|
|
||||||
|
**Exercice 15**
|
||||||
|
|
||||||
|
Expliquez les différents éléments contenus dans cette requête. La clé
|
||||||
|
privée du sujet y figure-t-elle ?
|
||||||
|
|
||||||
|
#### Génération du certificat final
|
||||||
|
|
||||||
|
**Exercice 16**
|
||||||
|
|
||||||
|
A l'aide de la requête de certificat, générez un certificat pour votre
|
||||||
|
clé publique. Vous jouez donc le role ici de l'authorité de
|
||||||
|
certification.
|
||||||
|
|
||||||
|
openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90
|
||||||
|
|
||||||
|
Affichez ce que contient le certificat.
|
||||||
|
|
||||||
|
L'option `-CAcreateserial` est à utiliser seulement la première fois.
|
||||||
|
Ceci va générer un identifiant (ca.srl). Lors des prochaines
|
||||||
|
certification (pour renouvellement ou pour d'autres domaines)
|
||||||
|
l'identifiant, contenu dans le fichier ca.srl, sera incrémenté à
|
||||||
|
l'aide de l'option -CAserial ca.srl
|
||||||
|
|
||||||
|
Pour vérifier la validité d'un certificat, on peut utiliser la commande
|
||||||
|
verify :
|
||||||
|
|
||||||
|
openssl verify -CAfile ca.crt moncertif.pem
|
||||||
|
|
||||||
|
**Exercice 17**
|
||||||
|
|
||||||
|
Vérifier le certificat généré.
|
||||||
|
|
||||||
|
#### ncat avec SSL/TLS
|
||||||
|
|
||||||
|
On va utiliser ncat qui supporte SSL/TLS.
|
||||||
|
|
||||||
|
1. Avec tcp, échangez un fichier entre un client et un serveur ncat.
|
||||||
|
Vérifier avec tcpdump que le fichier passe **en clair** !.
|
||||||
|
2. Refaire la question précédente en utilisant SSL/TLS.
|
||||||
|
- Le serveur a maintenant besoin du certificat, et de la clé privé
|
||||||
|
correspondante (option `--ssl-cert` et `--ssl-key`)
|
||||||
|
- Le client doit aussi se connecter avec l'option `--ssl`.
|
||||||
|
- Le contenu du "fichier" échangé passe-t-il encore "en clair"
|
||||||
|
?
|
||||||
|
|
||||||
|
3. Que se passe-t-il coté client si vous rajoutez l'option
|
||||||
|
`--ssl-verify` ?
|
||||||
|
|
||||||
|
ncat --ssl-verify --ssl localhost port
|
||||||
|
|
||||||
|
4. Avec l'option `--ssl-trustfile`, dites à ncat de faire confiance à
|
||||||
|
l'autorité de certification qui a signé le certificat du serveur.
|
||||||
|
5. Connectez-vous au serveur ncat en utilisant votre browser. Pour
|
||||||
|
cela, faites un fichier `rep.http` qui contient une réponse http qui
|
||||||
|
sera renvoyée au navigateur. Par exemple
|
||||||
|
|
||||||
|
```html
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>TP</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>TEST</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
Le serveur renvoie systématiquement la même réponse :
|
||||||
|
|
||||||
|
ncat -l 8080 < rep.http
|
||||||
|
|
||||||
|
Vérifiez depuis votre navigateur.
|
||||||
|
|
||||||
|
6. On veut cette fois-ci se connecter à notre serveur ncat en https. On
|
||||||
|
utilise localhost comme nom.
|
||||||
|
7. Testez depuis votre navigateur. Que se passe-t-il ? Dites au
|
||||||
|
navigateur que vous faites confiance à l'autorité qui a signé le
|
||||||
|
certificat du serveur (comment ?)
|
||||||
|
8. Malgré tout, cela ne suffit pas. Le navigateur devrait vous réclamer
|
||||||
|
l'extension `subject Alternative Names` qui permet d'associer
|
||||||
|
emails, ip, noms, etc. En l'occurence, il faut associer le nom
|
||||||
|
localhost au certificat.
|
||||||
|
|
||||||
|
En tant qu'autorité de certification, recréez le certificat du
|
||||||
|
serveur en ajoutant localhost comme nom associé au certificat.
|
||||||
|
|
||||||
|
openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90 -extfile x509.cnf
|
||||||
|
|
||||||
|
le fichier x509.cnf
|
||||||
|
|
||||||
|
subjectAltName = DNS:localhost
|
||||||
|
|
||||||
|
Retestez.
|
BIN
td_tp/tp4/cracklib-small.gz
Normal file
BIN
td_tp/tp4/cracklib-small.gz
Normal file
Binary file not shown.
BIN
td_tp/tp4/cryptogramme
Normal file
BIN
td_tp/tp4/cryptogramme
Normal file
Binary file not shown.
BIN
td_tp/tp4/signatures.tar.gz
Normal file
BIN
td_tp/tp4/signatures.tar.gz
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user