[PD2] Server done?

Co-authored-by: tsousa111 <tiagao2001@hotmail.com>
This commit is contained in:
Afonso Franco 2024-05-28 20:08:25 +01:00
parent 08a73a4f76
commit 49a29e43a7
Signed by: afonso
SSH key fingerprint: SHA256:PQTRDHPH3yALEGtHXnXBp3Orfcn21pK20t0tS1kHg54
66 changed files with 2777 additions and 5 deletions

View file

@ -90,7 +90,7 @@ func (ds DataStore) GetMessage(toUID string, position int) protocol.Packet {
err := row.Scan(&serverMessage.FromUID, &serverMessage.ToUID, &serverMessage.Subject, &serverMessage.Body, &serverMessage.Timestamp)
if err == sql.ErrNoRows {
log.Printf("No message with NUM %v for UID %v\n", position, toUID)
errorMessage := fmt.Sprintf("MSG SERVICE: unknown message!")
errorMessage := fmt.Sprintln("MSG SERVICE: unknown message!")
return protocol.NewReportErrorPacket(errorMessage)
}
@ -217,7 +217,7 @@ func (ds DataStore) userExists(uid string) bool {
err := ds.db.QueryRow(query, uid).Scan(&count)
if err != nil || count == 0 {
log.Printf("user with UID %v does not exist\n", uid)
return false
return false
}
return true
}

View file

@ -7,8 +7,6 @@ import (
"log"
)
//TODO: LOGGING SYSTEM
func clientHandler(connection networking.Connection[protocol.Packet], dataStore DataStore) {
defer connection.Conn.Close()

Binary file not shown.

214
Projs/PD2/README.md Normal file
View file

@ -0,0 +1,214 @@
# Relatório do Projeto de Desenvolvimento 1
## Introdução
A comunicação eficaz dentro de uma organização é essencial para a eficiência do seu funcionamento. No entanto, num ambiente cada vez mais digital, garantir a segurança e autenticidade das comunicações tem-se vindo a tornar uma preocupação fundamental. Em resposta a esta necessidade, este primeiro projeto de desenvolvimento visa criar um serviço de mensagens seguro e autenticado.
Para contextualizar o projeto, consideremos uma organização onde informações confidenciais são frequentemente trocadas entre membros de equipas distribuídas geograficamente. Neste cenário, é crucial que as mensagens enviadas e recebidas sejam protegidas contra acessos não autorizados e manipulação por partes externas. Além disso, garantir que a identidade do remetente e a integridade da mensagem sejam verificadas é essencial para manter a confiança e a segurança das comunicações internas.
Perante estas necessidades, o projeto de desenvolvimento propõe a criação de um sistema cliente/servidor que oferece um serviço de mensagens seguro e autenticado. Através deste sistema, os membros da organização poderão trocar mensagens com garantias de autenticidade, protegendo assim a confidencialidade e integridade das comunicações.
Ao longo deste relatório iremos detalhar as decisões mais importantes tomadas no desenvolvimento do projeto, bem como as medidas de segurança implementadas para garantir a confidencialidade, integridade e autenticidade das mensagens trocadas entre os utilizadores.
Algumas notas sobre o projeto:
- Optamos por escolher **Golang** como linguagem visando uma implementação mais eficiente, robusta e segura ao nível de concorrência. O modelo de concorrência baseado em goroutines e canais facilita a criação de programas concorrentes e sistemas distribuídos. Com uma sintaxe simples, semelhante a **C**, o **Go** promove a escrita de código legível e de alta qualidade. Além disso, o **Go** possui um ecossistema robusto de bibliotecas e ferramentas, tornando-o uma escolha adequada para o desenvolvimento de sistemas distribuídos e serviços de back-end.
- Implementamos algumas funcionalidades extra, como o armazenamento dos dados no servidor numa base de dados **sqlite3**
Nas secções seguintes iremos detalhar cada componente do sistema, bem como as funcionalidades implementadas.
## Análise de Risco
Esta análise de risco do sistema visa identificar as potenciais vulnerabilidades e ameaças que possam comprometer a segurança do sistema de mensagens. É essencial considerar os diversos fatores que podem impactar a integridade, confidencialidade e disponibilidade das mensagens trocadas entre os utilizadores.
### Potenciais Vulnerabilidades
1. **Comunicação Não Segura** - Se a comunicação entre os clientes e o servidor não foi cifrada, qualquer *man in the middle* consegue ler o conteúdo a ser transmitido.
1. **Armazenamento Inseguro de Chaves Privadas** - Se as chaves privadas dos utilizadores forem armazenadas de forma inadequada, como em arquivos desprotegidos, existe o risco de acesso não autorizado, comprometendo a segurança e autenticidade das mensagens.
1. **Autenticação Fraca** - Um sistema de autenticação vulnerável pode permitir que utilizadores mal-intencionados obtenham acesso não autorizado às contas dos utilizadores legítimos.
1. **Manipulação de Mensagens** - A ausência de mecanismos eficazes de controlo pode facilitar a manipulação do conteúdo das mensagens durante a transmissão, comprometendo sua integridade.
1. **Vulnerabilidades de *Software*** - Falhas de segurança no *software* desenvolvido e utilizado para implementar o sistema podem ser exploradas para obter acesso não autorizado ou comprometer a segurança dos dados.
### Possíveis Ameaças:
1. **Ataques de Intercetação de Dados** - Atacantes podem tentar intercetar a comunicação entre o cliente e o servidor para obter informações sensíveis, como chaves privadas ou conteúdo de mensagens.
1. **Ataques de *Denial of Service (DOS)*** - Um ataque de *DOS* pode tornar o servidor inacessível ao sobrecarregá-lo com um grande volume de solicitações, prejudicando a disponibilidade do serviço.
1. **Ataques de Engenharia Social:** - Atacantes podem tentar manipular os utilizadores legítimos para obter acesso às suas credenciais de acesso por meio de técnicas de engenharia social.
1. **Exploração de Vulnerabilidades de *Software*:** - Vulnerabilidades conhecidas ou desconhecidas no *software* utilizado podem ser exploradas para comprometer a segurança do sistema.
### Propriedades Requiridas:
1. **Autenticidade do Remetente** - O cliente deseja ter a garantia de que a mensagem recebida foi realmente enviada pelo remetente indicado.
1. **Confidencialidade das Mensagens** - O cliente quer assegurar que apenas ele possui a capacidade de decifrar as mensagens que lhe foram enviadas, garantindo assim a privacidade das comunicações.
1. **Servidor Malicioso** - Os clientes pretendem proteger-se contra a possibilidade de o servidor agir de forma maliciosa, garantindo que as suas interações sejam seguras e protegidas, necessitando de mecanismos que garantam a segurança das suas interações independentemente da confiabilidade do servidor, como a utilização de criptografia *end-to-end*.
1. **Comunicação Segura com o Servidor** - Os clientes exigem que a comunicação com o servidor seja segura, protegida contra acesso não autorizado e intercetação por partes não autorizadas, garantindo assim a integridade e confidencialidade dos dados transmitidos.
### Medidas de Mitigação:
1. **Protocolo de comunicação** - Utilizar um protocolo de comunicação que garanta a confidencialidade para proteger a comunicação entre o cliente e o servidor.
1. **Armazenamento Seguro de Chaves Privadas** - Adotar práticas seguras de armazenamento para proteger as chaves privadas dos utilizadores contra acesso não autorizado, como utilizar *passphrases* para proteger o acesso à *key store*.
1. **Fortalecimento da Autenticação** - Implementar métodos robustos de autenticação, como certificados digitais, para garantir a identidade dos utilizadores e proteger contra acesso não autorizado.
1. **Validação de Dados** - Implementar controles de validação de dados para garantir a integridade das mensagens e prevenir a manipulação de dados por partes não autorizadas, como, por exemplo, assinar "hashes" das mensagens enviadas.
1. **Atualizações de *Software*** - Manter o *software* utilizado atualizado para mitigar o risco de exploração de vulnerabilidades conhecidas e garantir a segurança do sistema.
Esta breve análise de risco destaca a importância de identificar e mitigar potenciais vulnerabilidades e ameaças para garantir a segurança do sistema desenvolvido. A implementação de medidas de segurança adequadas é essencial para proteger os dados e garantir o funcionamento seguro.
## Decisões de Arquitetura e Implementação
Tendo em consideração as vulnerabilidades e ameaças identificadas na análise de risco, foram tomadas várias decisões de design e implementação para garantir a segurança e autenticidade do sistema de mensagens. As decisões tomadas visam proteger a confidencialidade, integridade e autenticidade das mensagens trocadas entre os utilizadores, bem como garantir a segurança da comunicação entre o cliente e o servidor.
1. **TLS (Transport Layer Security)**
- Cada conexão entre cliente e servidor é protegida pelo protocolo TLS, garantindo que a comunicação seja segura e privada.
- Cliente e servidor trocam certificados para autenticar as suas identidades.
- Ambos verificam se o certificado foi emitido pela Autoridade de Certificação (CA) central.
- O cliente verifica se comunica com o servidor legítimo.
1. **End-to-End Encryption (E2EE)**
- Ao enviar uma mensagem, o cliente assina a *hash* do texto simples com a sua chave privada.
- A assinatura é anexada ao texto limpo e esse conjunto é cifrado com uma chave de sessão gerada aleatoriamente.
- A chave de sessão é cifrada com a chave pública do destinatário, Isso garante que apenas o destinatário possa decifrar a mensagem.
1. **Visualização da Lista de Mensagens Não Lidas**
- Quando um cliente solicita a sua lista de mensagens não lidas, apenas o assunto é enviado, não o conteúdo cifrado.
- O cliente deve decifrar o assunto para visualizá-lo.
1. **Visualização de Mensagens**
- Quando um cliente solicita uma mensagem, é enviado o conteúdo todo da mensagem.
- O cliente deve decifrar o assunto e o corpo da mensagem para visualizá-los.
1. **Troca de Chaves Públicas**
- Quando um cliente precisa da chave pública de outro cliente, solicita o certificado desse cliente ao servidor.
- Verifica-se se o certificado foi emitido pela CA central e se pertence ao cliente desejado.
1. **Verificação de Inputs**
- Tanto cliente quanto servidor realizam verificações básicas nos *inputs* para garantir a sua integridade.
- Ambos desconfiam um do outro e verificam cuidadosamente todos os *inputs*.
1. **Confiança na CA Central**
- A única confiança absoluta neste sistema é depositada na Autoridade de Certificação central, responsável por emitir os certificados.
## Certificates and Keys
Para gerar os certificados e chaves necessárias para a comunicação segura entre o cliente e o servidor, foram seguidos os seguintes passos utilizando a ferramenta **OpenSSL**. Estes passos incluem a geração de chaves privadas, certificados e *keystores* para o servidor e clientes, bem como a assinatura dos certificados pela CA central.
1. **Gerar *CA key* e o *certificate***
```bash
openssl genrsa -aes256 -out CA/CA.key 4096
openssl req -x509 -new -nodes -key CA/CA.key -sha256 -days 18250 -out CA/CA.pem -subj "/2.5.4.3=CA"
```
A *passhphrase* da CA é 1234
2. **Gerar a *server key* e *CSR***
```bash
openssl genrsa -out server/server.key 4096
openssl req -new -key server/server.key -out server/server.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=SERVER"
```
3. **Assinar o *CSR* do *server* com a *CA***
```bash
openssl x509 -req -in server/server.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out server/server.crt -days 1825 -sha256
```
4. **Gerar o *keystore* do *server***
```bash
openssl pkcs12 -export -out server/server.p12 -inkey server/server.key -in server/server.crt -certfile CA/CA.pem -name "ServerKeyStore"
```
A passphrase usada para o *keystore* é server
5. **Gerar as chaves e *CSR* de cada *client***
```bash
openssl genrsa -out client{NUM}/client{NUM}.key 4096
openssl req -new -key client{NUM}/client{NUM}.key -out client{NUM}/client{NUM}.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=CL{NUM}/2.5.4.3=Client {NUM}"
```
6. **Assinar os *CSR* dos clientes com a *CA***
```bash
openssl x509 -req -in client/client.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out client/client.crt -days 1825 -sha256
```
7. **Gerar o *keystore* do *client***
```bash
openssl pkcs12 -export -out client{NUM}/client{NUM}.p12 -inkey client{NUM}/client{NUM}.key -in client{NUM}/client{NUM}.crt -certfile CA/CA.pem -name "Client{NUM}KeyStore"
```
A passphrase usada para o *keystore* é client{NUM}
Neste processo, foram geradas as chaves privadas, certificados e *keystores* necessários para estabelecer uma comunicação segura entre os clientes e o servidor. Os certificados foram assinados pela Autoridade de Certificação (CA) central, garantindo a autenticidade e integridade dos certificados emitidos. Os *keystores* contêm tanto o certificado quanto a chave privada do cliente ou servidor, protegidos por *passhprase* para garantir a confidencialidade e segurança das chaves privadas. Este processo de geração de certificados e *keystores* é essencial para estabelecer uma comunicação segura e autenticada entre os componentes do sistema.
### Certificados
- **Autenticidade**: Os certificados são assinados digitalmente pela Autoridade de Certificação (CA) central, garantindo sua autenticidade. Isso significa que os clientes podem verificar se o certificado foi emitido por uma entidade confiável.
- **Criptografia**: Os certificados contêm a chave pública do cliente ou do servidor, que é usada para estabelecer uma comunicação segura por meio de criptografia assimétrica. Isso permite que as mensagens sejam cifradas pelo remetente e decifradas apenas pelo destinatário.
- **Verificação**: Antes de confiar num certificado, os clientes verificam sua validade, incluindo a data de expiração e a correspondência com a entidade emissora. Isso ajuda a evitar a utilização de certificados inválidos ou falsificados.
### *Keystores*
- **Armazenamento Seguro**: Os *keystores* são arquivos protegidos por *passphrase* que contêm tanto o certificado quanto a chave privada do cliente ou servidor. Essas informações sensíveis são protegidas por meio de criptografia, garantindo que apenas o proprietário autorizado possa acessá-las.
- **Proteção da Chave Privada**: A *passphrase* do *keystore* protege a chave privada contra acesso não autorizado. Isso é crucial, pois a chave privada é usada para decifrar as mensagens recebidas e assinar as mensagens enviadas, garantindo a autenticidade e integridade da comunicação.
- **Confidencialidade**: Como os *keystores* são protegidos por *passphrase*, mesmo que alguém obtenha acesso ao arquivo, não poderá extrair a chave privada sem a *passphrase* correta. Isso ajuda a manter a confidencialidade das chaves privadas dos usuários.
## Criptografia
É importante destacar que, para garantir a segurança e integridade das mensagens, implementamos um protocolo de comunicação seguro. Este protocolo utiliza tanto criptografia simétrica quanto assimétrica. As mensagens são cifradas com uma chave de sessão gerada aleatoriamente, que, é cifrada com a chave pública do destinatário para garantir a confidencialidade. As mensagens são também assinadas com a chave privada do emissor para autenticidade. Dessa forma, asseguramos que as mensagens sejam protegidas contra acessos não autorizados e que a sua origem possa ser verificada.
![Digital Envelope](report_content/digital-envelope-diagram.jpg)
### Networking
O canal de comunicação estabelecido entre o cliente e o servidor nesta implementação garante uma troca de dados segura e criptografada utilizando o protocolo TLS (Transport Layer Security). Ambos, cliente e servidor, empregam configurações TLS para cifrar os dados durante a transmissão, assegurando confidencialidade e integridade. Durante o handshake TLS, o servidor valida o certificado do cliente para verificar sua autenticidade, prevenindo acessos não autorizados. Este mecanismo robusto de segurança protege o canal de comunicação contra escutas, adulterações e ataques do tipo "man in the middle", garantindo uma troca de informações segura e confiável entre o cliente e o servidor.
### Protocolo de Comunicação
O package **protocol.go** define um conjunto de estruturas e funções que representam os diferentes tipos de pacotes que podem ser transmitidos entre o cliente e o servidor. Cada tipo de pacote é representado por uma constante PacketType, que indica a natureza da informação contida no pacote através de uma **flag**.
As estruturas de dados definidas, como `GetUserCert`, `GetUnreadMsgsInfo`, `GetMsg`, `SendMsg`, `AnswerGetUserCert`, `AnswerGetUnreadMsgsInfo` e `AnswerGetMsg`, descrevem os formatos específicos de cada tipo de pacote a ser enviado e recebido. Cada estrutura contém os campos necessários para armazenar e representar os dados associados a cada tipo de pacote.
Além disso, foram implementadas funções auxiliares para criar instâncias de cada tipo de pacote, como `NewGetUserCert`, `NewGetUnreadMsgsInfo`, `NewGetMsg`, `NewSendMsg`, `NewAnswerGetUserCert`, `NewAnswerGetUnreadMsgsInfo` e `NewAnswerGetMsg`. Estas funções facilitam a criação de pacotes com os dados necessários de forma estruturada.
Para facilitar a serialização e desserialização dos pacotes em formato JSON, foram implementadas funções `Unmarshal` específicas para cada tipo de pacote. Estas funções convertem os dados do pacote entre o formato JSON e as estruturas de dados correspondentes, permitindo a comunicação eficiente entre o cliente e o servidor.
Este package serve como uma camada de abstração que facilita a comunicação entre os componentes cliente e servidor, garantindo que os dados sejam transmitidos de forma estruturada e *standardized*, facilitando o desenvolvimento, manutenção e expansão do sistema de comunicação.
### Sqlite3 Database
Como mencionado anteriormente neste relatório, uma das funcionalidades adicionais implementadas foi o armazenamento dos dados do servidor numa base de dados persistente. Neste projeto, optamos por utilizar o **SQLite3**. Este é utilizado para armazenar as mensagens enviadas e recebidas pelos utilizadores, além dos certificados digitais dos clientes. A escolha de uma base de dados permite a persistência segura e eficiente dos dados, assegurando que as mensagens e certificados sejam armazenados de maneira duradoura e acessível.
Em relação à segurança contra ataques como *SQL Injection*, é crucial adotar medidas para mitigar esse tipo de ameaça. A utilização de *prepared statements* é uma prática essencial para prevenir ataques deste tipo. Com *prepared statements*, os valores dos parâmetros são tratados como dados e não como parte do comando SQL, o que reduz significativamente o risco de injeção de código malicioso. Essa abordagem fortalece a segurança do sistema, garantindo a integridade e confiabilidade das operações da base de dados.
### Verificações e Testes de Segurança
Para realizar testes e verificações de segurança implementamos também um *Fake Client, Server e CA*, que permitem testar a segurança do sistema em diferentes cenários, como tentativas de intercetação de dados, manipulação de mensagens, autenticação fraca e outros tipos de ataques.

54
Projs/PD2/certs/CA/CA.key Normal file
View file

@ -0,0 +1,54 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJtTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQG3DZ1dZ9W2PyggmI
h4pC0QICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEED6e2w74Q4EtFq96
cSxKrlMEgglQ/ujttAnFkcPv9X7Xweo2oT8HHr5nAs3Np1Ew4dI6Uu34zOwXR5F5
hR6I3mrH3Ir9/LO5hCvW5ticCJsoO25+f59u/zam8j0AGO2WYiaHLLhIHi1qJlEh
m50vVqO+9HdQqUqYoTIfocz4Dz1zv6OEzsFGrhIAk+QTDgxxVFj3g0CYK24AZ+gj
YMO/XtWljYjXKg/JH6jgLqz/CKMsPimLGXqkOD2/btf8MXxgDgMmRKa/4OBeX/19
fA+IMcJ0XzGW5Y7rnHGI/5poKUukD52aGfC4jaXtT4QCEC+bnjjYZsA7m6h6D881
fXTcm0ADfSR2OuuTWolfpQt7QAMnOozFCOX+EHdOFzqcJyVu/3d722ni/8TZarB0
zGel7DhZ+vtOP7IwnJxrZB5QyRgnzj7v+inQauaItk/OJ3wcQue5YQ4qf9A6Mcob
IhmRIvZtFg/AZ6ENzzJtZDl7B+lyhBC1NVY1V9s2dXSKtjhk2B4XomBf1Wrf7Imh
+gb4Byncb3sIHbjbgmDg/oIb/gnT0XXap+nfG6JxhB5aawXDHNx2uz5lCl15X4FN
+UAmFeAnnEbauTIaK1sci8EzOZMJ6U7OH1itlUCcIYAR1rD1xG0bdfc+tlZzRrVo
XZJtrLtLCUOQCcBpmM+qIRQx7UN4m98VKdruw65UZbh8RvTlSfuRMlH82f9Y9g6R
roxnfx5QURT6R2DAkEYX4eQqcwjpjJkgRS3R6X6prD797cVl19/TShsuLD1PWPLH
4BQLOK07aDM4RJf75rmTBk861kuzAsMNTqBu0RXbam8jzn/L7Kx/h6WCbvm14EtA
2C53k0yYyEkdI1jmSGsgxgUMO7LrpMQjceL4xvX8v/nxopzI7mOEK4wk4FsyUfBl
mrBy8rYt6q/JyK7i8sBAY91QTaaKWLH/SWJrKG25vp3z2KxnTy43xSuTN9Lknjmo
gm/4WvUmhpwEO2Q3+mGVpBWV9pTG7NHg6rDKPsMt/+eYdGaR51fcBMpktkOXLETb
d7njjjaFDu/PHP+ZRxbUZZMtx+uSiohg8T09q2OOP1RaujuolHRFbWD5Tpea7e8c
oQuwcEZRWlxuPseg5dkwSbQ9ZIj1Y2ayPRcLhIYubf8LI/Bd7OS2doablmPDBQdv
pZJAy/Y+2j7c0wI3ogI419cUjAHL+BEhUI2Tp/zqA1qsgB03QVk1GF/K+3YGQcjU
UT1s5Z4On9GPuyVsDHYfeF9Y1bWFKgdFMgdndw+Ld2GJDf+BXjH0BDeVwWkkd2ab
EzDu+PV1yO0/KQ6jHSjXB3NDPppu7mgMao2Ls8LoQnkXyX5I42Hgaz0GH7rKU+Io
Q0OxA0ODsI0mY66Iort1Q5j5NvfftTz9qW4pOCU7fMNzbQO3GRVsNvcYyNCja3bm
ojiX1Z8eOwWZ+L/Z00I2BmnP1YAjChtXcuIwxbeC9pQBXiL6VQezzkARtb3LGpkc
ZIqpQkV0lqUHr/aN3Apaz/W3bxk8IprKCKEC/9S3Z0NX9rtcfr10MtUsWDM4+Du8
4dBiaa5GcwjIkI+g8VFdF3BH7VlRDwqGH6Wy2Oe1WkCNibgCAjB5xU3YHTj8rR9Q
pI/UQKMC8i0VSAnjL16qCWnW0Wsp8zQo8dna/kk1BBBnxILWZeE+cyadf7N/kPPy
yZJFKZT992VKPOY7CgK8Z1+EahLE0e7VUxjCK0iNmJNtnyd5AetJts2g3HAcI39M
z4bWUtdoyGbMopuKC3dW1r/4/KR0unYum1cmQVoTYwsUTC9q3jGMNFG+XeaF3olh
8K4BDovNFy9IAPYzGD0QkuK7jAFfTvFEo2VEQTGtupCtRUz3fTnrWi1TrqjLoJcs
7bNMBSiMuDJ7qoCFhxFCnBA5eejYOdI4y0qFw3D4URFDSYKVsId13PORavE2nzFz
XAvUsVLZZn/jsYv1C0kRZ55fRyO2McCHrItWlMfCe6HgUxOZ9Tp2ufSyPKvsntWs
jWzNZtJU5ijgvz2kxDLYVAeIOefeCQOcUDMVgem+mssu+E79FFc0ecRcypLSm1sV
lFlgXaNz1GlpcGfQUlM/bF1tNdIVMNpQI1siUj+EYMfbCebFk5K7jdb731NNBiVW
4tnTP0cLDJOTJAETmp0iRmXqtsgq5sUU5Y1NUTocxeDeATGGEyfMcgSiTuZfw1Ny
f61RqF7211pMrErrDjmtl6cTSh0jW4I90HR/1QGrkBQ6AIguJSs3gcodjzHzb7P9
lzW0XHpf+DdwmgwdrZ4XxhFBvy0mf+90v6rQv7RPi7GnoxUQ5Y33CAaAEtgjpeSM
/GYmJ6KS+422Qnll4kcY8rlkNSAmzDxVdLubHlZwBXlKHgqQajggA8RfiukKTxEx
DcUDhP/gsRwkaJKojeftcSxtmnSH6XMAFNKm7bNTXXxjX9kFJpz1sPpV++83R/ET
gqhfaD9NE0Frc6GQX8ai6Iw5Ut8OTRWcdZRMy6EOsQUTtdUG5qNx9ZHKx5o0OlXv
uhgWifOWKDOJUlcxT0xOCHCFF4ZVxcBj2lM2SLTYMYoKGjqdkBMmZBF7t1zIRQkV
TDzThlYx9D6ubCctKxweug2Hfyy/gMABMPKaCU5T3u2vI9LOWxDHRLUN69AHXksc
AnmaoX01B61XC0PdZLTqa1ct/II3oSRJ55kfqcLZYcaz1AWyvHPdDIXzgz+lAJ1Z
7nQWAbFNUgrJUu+3WzcZDmokl2o7xQ6nrYHA8UWRh1ftjkw6K8M1/ggdegBU+3nF
0ZoPsUnGc91AyMVbzAVm7EJ/xSe5azHQ+jJO8mFzDVPdyGaCflYyAMCPjgQFEO7U
ZJ8yhfWLD+XkLDUJTWi3HXF9ntnIYomP8eXcEsOr0PjwQjDAzxjXAApLJUcyKY2t
fQ7tp5T2TgFfcCmP0YF0fa1H1dwnOuDu4+ftdPBkARGAMkdPV8mOptkpIVT9e6Cu
dlZx5TO6qKJv57mlBezWGgwRlZL4olAn+FBz0j0Kd0bYwLhIgNkYU4Pz7SqUljyd
9U10VrrZiS1/hlQ2ec8M8JduDCI2Df8JBwgBNcVINAOynLAspZwjxIPY0unZXur0
MNoaStKfZ8zN55yvM64OkcFBEMDeZxNPcaNS2Lfrs7UxSzafcEnz6bs1qodQFv4R
AYPF76qkFK87CA1LzcSQqNrn9HeEpOm+p/CZxx7lowQQUtK/8836f88=
-----END ENCRYPTED PRIVATE KEY-----

29
Projs/PD2/certs/CA/CA.pem Normal file
View file

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE/TCCAuWgAwIBAgIUeu0iePpZFCl6i+Ox7QbXywinn+wwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwIBcNMjQwNDE5MDAyMDE5WhgPMjA3NDA0MDcwMDIw
MTlaMA0xCzAJBgNVBAMMAkNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAv7oZ8bld3ImFrkmRf28EbkFZ3xv2FxJP8+eqv8qufKeYyEm9VEzAM7kpsaIG
OoEC5yBOVQ4uhC8aCcknm9OU/m5IFfMGAXwj9cWee9KZZM5ma2W/rvO3z6JcBTP6
mEuQZI8GVST5RqDzEhDZSujerN9/SaHnCwqPshUUbft/yMF0oHyEhmpNg+0Uu8WF
4ck0W9rlBS+z+PfMy2Y7iTM9o21q2fPRbXDxoDSCebMN8NiB9/RK/kAcRZqTYd+u
LsIx61nTphhk4uNs7PQ82ABXhQTKnU1svTVInjQfYDAypr5cPMwut1TSieCBS7/N
Xaod/b2voKZihqQ1yYWwdanj7QarySK6MC/JAoLlq4KE6/YL2788k+eu7cP6v4Yf
k2o2IPA4/9LcZ4nMLmKszamw5OZmyzGtYifE2wvabileitn06oiutMIdm9EUthrs
/6h/OkILQeh6tOuy3NqSj1rf0rs62/OC3k3BWf/WFwqLileCpxwQZXOWiXFznuvP
0T9QxCFj3HacdhiXo4oejpIlGnclBSZ7B96dR7xGAaXoOL8EatYVZGB8LKpx8H3/
vgehVevNRz2/WvYfJATnvaakM+i/TYhX027Exi+LvdyMH4C1xRiqDvC3kYzZwakN
1ZCpz6fYmhWNqW0rzu3ePRpYHSGC0hq1WTRfHaQvAVMJiUcCAwEAAaNTMFEwHQYD
VR0OBBYEFMVE1jz77WweC8ao7bVYxujCdbDRMB8GA1UdIwQYMBaAFMVE1jz77Wwe
C8ao7bVYxujCdbDRMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AI7KNfTFRFCdLIxDkVzG6/FZx5ue++xGMdxwrVX8sX2mib9yMaAMbj3TPX0f/PDD
avUBK5pgNi9cV/GsXw0vnrJ9R9Ou5pYJ+NeaQZoO+YTHDnqJL7Ro3Q1BcRG8S+Q6
+YwoiXzghLebq7r81yhQXeS3Ax7SHlz+rXoDQJFSdDBPMJSFgJs2YPTRDPNEveW2
wvFAdIK5KzB2gaeQRT/vix4jFasXUogRpLXWCDFJFYPd0iaTrzP1K1mDTHDD/pFB
R3AnMxWp3Plxxr/jO6Djb0GgRjp5q4uoZAYpwZfE70M9jafqoA20t2Rxtorj+SA0
+o2uG72ssTbw5cfQy+uBnQiUghvsw3U4D62d+IxW9gtbOBGES4TIflKsUnJ36RKx
EQaPYJ6VhgBDyGoqBmANjfV4u3Jz7IlxQyeA0JzhuOSfenQaRQzjvaj/4SlYYfhm
tKgEuQf6XaiXa/PWKIwwT49TZ7ZQB+g1xTD43s9PZ883byZPEolLe12cvJ918jQf
/8VFLCHCuV+k+g8FIt/dOgalHmM1hh8uzqiIk1Rtp8YPsuUNO4ZeHQ+ANGO1WqXx
GYNa4Unhuz3+VNxbctAaSNExvzwYIqEdNdZjxOYw09fOYQUkYDN+7gB90GCstCsJ
10KMhfRQQm3Fq8CtnOomgUmgcawPDuFOThLuU4m1dkcT
-----END CERTIFICATE-----

View file

@ -0,0 +1 @@
7C475B59D1510F54E042BF4BFDBE811BF4EDAF37

View file

@ -0,0 +1,54 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
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
-----END ENCRYPTED PRIVATE KEY-----

View file

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE/TCCAuWgAwIBAgIUNae6TxoDs5d/kuQMGrNstWsNYCUwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwIBcNMjQwNDE5MDAyNTAzWhgPMjA3NDA0MDcwMDI1
MDNaMA0xCzAJBgNVBAMMAkNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAuYf0lxxLL6o2XkvhyAH5v454URbhRS1s4K0U2F31wY5DpmveKI2/amRuvNUD
URMV5VB+REWSMMJmY4bxqJ6CxqBeKNE/RXTb30N3XDyZ5tqKb/R4GnvHXZ0QE6xx
Gar0ao50/K4pcZmUjhVk2pLoBp+ffGym8ZKBkODDMzVjwEq/pWgcBJK6qe1N/Dyj
qurysdc+xklV7hJhTU88/lVUe5cvXzD1JSVCsJlkZWlftQ7ARmyPTpAi+yI+R0V5
ivCBvMgHvfxmzrBQbMX2JrM52wuQFN+ORCSrhIjUUr4s8lKiIqbwdqBLwMREWcfA
/uUGz0iZCQN2qcScQer3vLsw36u1xbnuVSs+pLgZ9RRzjRCuBs8P4xUqpmagqDov
itB8v65C0s0KOmBlyUKyS3SH9jx5efTAvy4f4HTmyGoTBV+ioitgE9gcCSn1tvXd
c/vyxUQfGCa15ILrbI/QFvbaFyqUVfsVbP/VtugaGd+3asrS/9nLiyAkXYTePOBp
e2UvHVbBwQoCawEycthq1cUBMBe5OPmMr20A08OTNLsHa8/tFfN2+3Kv+Ri13AX2
NMFy+U5bJV0+WMF8vu0dIXRVajNu/PmclcsZLQ11bvUI+x+JemNpaVvojXqpI/KN
PdLo37OeGOtm1uskc96n2fjurPJTBVfmmJ+L5eGC5mODkPUCAwEAAaNTMFEwHQYD
VR0OBBYEFNVmKiwSu16jTsYiNfN2oyxpsY9tMB8GA1UdIwQYMBaAFNVmKiwSu16j
TsYiNfN2oyxpsY9tMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AHCnrPuTW2NNuQRgwOFSp+llH0Jn4dbCl1IDYzmr6nZBtxWaWr/NxKq6SLY4btF+
6C/TAwHw5etmdmzSI/9J/3fEf5C1xvWbDbzDu5W+/pZZ2KPDnPeqnDj9OzMhliEA
SgHKnwg7cBMaRRRiJJcDKUlj9zzHu5loAhwmHRkhvXmQFeEiDmacjU0Xhk9RiObJ
9i+LVFiCHupJ/iIusk+PpKoBtbWdkFHhPvb7xEvLRrM82/fK0jMkJsnYGK6aNsUH
qnqgZHa/3RP6zZStqE3FggsWHv2iC1NX0joMgg6lo/716SlyzL4ZdsPJWAhx5jNf
qTT3doBBZ4OMoKsbQL4UTO8yINzRY/1G7bVDrYl7VOI0XgKfqYsrSsIQgCr7gj4W
IM7Kyib7VOgooCvanxvZg1awIWMqiiGeG895kvtf4SkQkAMgfpE95lR2B6Ziz86J
AS/MKXbUtEAP7pr29svLHPv9IKqsXWrMdSVsDT3jkb0IYmm936vXDfmj/sLgfa03
GgIq8qhpNML/5b0sX7UqDGVXO2lxtCDrlRTiViwqyEsmfMNHOCyO43AwZTnRbO/0
jJFaB6zUsRKQrBUyIB2ZYdMbHarJHGahtiN2YT6cf8vKqvj56gpbaRq4EDYAnNqj
vO7rjSuTrXhevYHYUI/9qlMl00iz829IR5ixaa4k1sk4
-----END CERTIFICATE-----

View file

@ -0,0 +1 @@
7F4C6BBD8E095E37521D85095EBE463D9916EFB7

View file

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUf0xrvY4JXjdSHYUJXr5GPZkW77cwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyNTE3WhcNMjkwNDE4MDAyNTE3
WjA3MRQwEgYDVQQLDAtNU0cgU0VSVklDRTEMMAoGA1UEQQwDQ0wxMREwDwYDVQQD
DAhDbGllbnQgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMw0zgbG
HdyiHu8ktYTH1BvdbhC5ml4MC9SEfTtCK4PGo4bUIQvjM3hYBu90tH8/6Jzx4dJ8
AvWFDUnQJ6bkUFLLA7TivggBMQM6lbsX1Aqd4XO3+U31O3GJRyC5ikqv/JHSSKbP
HE2jbUUR3StJqKMVLmTxVkLsU+USDEj3+dRMST/IHIIL+hrO7mMsI7XzjMQELAUi
GCF6Em+CuitpNr3mMQhOMpA0ggM1D5vtzale4WYcj4sEo+9GSBKRwVBqhxKM/3Kn
1yY8G399RLqQAX+tHmb2jNnKwUm3oblqLqxaqvaRUv0HRcvMuKdQjWki+lwJE1Fd
OintXOGoFx7fRF4v3kAdLFDF4jXV7roBCWchWNKFTBWHP3Fu4MnI3whO8ixRyWid
FQS8mdEpEnjLeRohmX1PQ84x5Ln1EhhC/laJlfMr3koxrQEtYd2CHYm2y+L0ms9s
SVIQrSkhjYvFFckB60sQ6EAx8+BlJ0W5AcHOhGUZ+3uWN2SgWaCQon01ArV/sIT4
YFg31RB0ikL10HnpHrUZZbhZJDp8RT2lp3QdXonY3M9gap/K5UFW+0fVER1UrBXk
DGDkbvAMLFCAmUnbFgFZ4DOYoK3L29z8XomfhFP/J4OP8a/LrPrP8XFb1UtYey9J
ceTb7pJjbPD21KdBmbKtCeI/Y9xCC6OhE2ZZAgMBAAGjQjBAMB0GA1UdDgQWBBQj
r4/kiltPFckuHavkpQM+dkvY1DAfBgNVHSMEGDAWgBTVZiosErteo07GIjXzdqMs
abGPbTANBgkqhkiG9w0BAQsFAAOCAgEAJKTSFdUCVPDTgUC0x5gVKn8f+sYVkmga
fQwkEL8+E0fDul0Wa6vc9B4qLzRlpiY1TXSBVzI3M/Hpx9ffchHf80CBKvprdWaa
PO7GnTFsLueT0F74BQhk+64xeQjEGpooJCX6dxeAkSbPuLThs5zC7oRb02uLH0oY
mNgZ1MRfw2uDWLwODgkIrYZjzG2MV2nRRY0XWkiYBQFHAIqpklGN2LggwtADWVOl
baFVWQ8JVw1agrUnXpIybIhXoKGZQwM3H66XdVUoyORX647rr3kq6By/oPvkZXoM
gmJb2qO5ruiCw/KTw1BGG+OxXU0xPPBAj7qddb7foAdvHPvEGArRa+Pbc1nOF4O4
2TDLfcsSp/dDL3AgRuXhcLaUeIgbaKZiLLQHL1Tgtt1BO0Qhc8SibnWIprS5itqv
SmIodC5Vly1s2cefA+xwex9qAqmnHI1lKwZ1Aq6wqm7AP2YzJ6/uGN46wSZghfLv
Gzzxd3qHnISvRzY7/2AbA2H7QpgWuJlQRznUPJ4gcTD2HZpoQBcqNBApwtA/aKUh
jVTTG84fGvsmOG1zZiWxR8jdaU6iszh+u1Vn5rCa3wuIVoNNQkwJXUH7tEfeulwp
7xr1nN9k9IrieB6MQ1Mmg2GDYPQHWx3HV/j46adye0GMap4mMEYm1vN0ZV4hw/yv
z1Oh6ifZdsQ=
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEfDCCAmQCAQAwNzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDDAKBgNVBEEMA0NM
MTERMA8GA1UEAwwIQ2xpZW50IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQDMNM4Gxh3coh7vJLWEx9Qb3W4QuZpeDAvUhH07QiuDxqOG1CEL4zN4WAbv
dLR/P+ic8eHSfAL1hQ1J0Cem5FBSywO04r4IATEDOpW7F9QKneFzt/lN9TtxiUcg
uYpKr/yR0kimzxxNo21FEd0rSaijFS5k8VZC7FPlEgxI9/nUTEk/yByCC/oazu5j
LCO184zEBCwFIhghehJvgroraTa95jEITjKQNIIDNQ+b7c2pXuFmHI+LBKPvRkgS
kcFQaocSjP9yp9cmPBt/fUS6kAF/rR5m9ozZysFJt6G5ai6sWqr2kVL9B0XLzLin
UI1pIvpcCRNRXTop7VzhqBce30ReL95AHSxQxeI11e66AQlnIVjShUwVhz9xbuDJ
yN8ITvIsUclonRUEvJnRKRJ4y3kaIZl9T0POMeS59RIYQv5WiZXzK95KMa0BLWHd
gh2Jtsvi9JrPbElSEK0pIY2LxRXJAetLEOhAMfPgZSdFuQHBzoRlGft7ljdkoFmg
kKJ9NQK1f7CE+GBYN9UQdIpC9dB56R61GWW4WSQ6fEU9pad0HV6J2NzPYGqfyuVB
VvtH1REdVKwV5Axg5G7wDCxQgJlJ2xYBWeAzmKCty9vc/F6Jn4RT/yeDj/Gvy6z6
z/FxW9VLWHsvSXHk2+6SY2zw9tSnQZmyrQniP2PcQgujoRNmWQIDAQABoAAwDQYJ
KoZIhvcNAQELBQADggIBAKkdNU5DjB7stz9pVaU7fee9l4c7V0Qzcsk3ZHAtWR7h
DtP8c44d0Dk4Gb8YIgHcBH8x8RNYjWDUui74H5klhahWtuyaUXF8wh1KgFZ9qr05
xlZ0al6wBRlDclWZNciCDAyDzk9NYHeV6vIsNvlZcf9rdAxdfNdx1ufQno6yhcvW
xeJBy6TE+6xfj0YMagTCRQ3hXH/75BbMalgJmuAXoy1XhTISSOqwzm4AGbOhxwLB
aeaj5YsSYvliZP8lSMfak4OMN3yqmS++q2G1si2KIXYRN+v3sFPjdKnfwBWc99nH
4NyoKg/lWR4Bd4wmVESjAnS3YdtZ64L+XRGn+y2kdQPFBCEetnSY7qdOYBWvsHAc
4qYtmbMEmOr029s+c5qeSsA1+3lb98bpnaDPMIpltIK9ZNbGJ0vB+Y4rzGpHyGzu
D6bnuNRpB9e1+3nfY8W4WgQlt3wAtmtJ+3sG0VvHkIhADE2bkcreSvSJDc8J8gnc
EmgdlhBvjbaTdjbfbH6YZ/4+2QOQf7k/h00lnc7VqBXT9ly7TN7gvRWCVQdod2NS
3NjOTAocLRgZNzMFFGScbs6+UtpO0ySaWMUyyAs+TukDSbtEQIQQkKEbCJF1V1zH
FXEw7Ex1VXL8zkO72/BovMQRurSd1Jeaqy5nf7EgHDSA45Tuj5XlTnuYuy8TzwTO
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
nlSNqNapuhs7gJb7GzcRetc4RG/EJUE=
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBDCCAuygAwIBAgIUf0xrvY4JXjdSHYUJXr5GPZkW77YwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyNTAzWhcNMjkwNDE4MDAyNTAz
WjAnMRQwEgYDVQQLDAtNU0cgU0VSVklDRTEPMA0GA1UEQQwGU0VSVkVSMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAo9N5whjSzDHjlxb0q/AjYRljsT90
CFSUc84rvYmkgaHAtOQ0YjGuLXbjCeKgmk3qfg282T3qiVtZsjYZ5fzFON/q2pNu
tchfg7I327iKTMKb1EKbgTxXCNen6gZuHp1QxkedaKphZ/RT/Mk/MU2h+jyhdvPS
r1syVAae3M+u8/WAoliR/Utt2zXRbYv64fVnKgbilBtu364Pmr5bedkc70LX5DuJ
UIvYmn76SpFXLfTMF7NgfkuvZTJxIThncd4dXKgdXdGbmtLUsWJrjl2nBnbE0ir7
U8h9pi20LkZFAZLwGi8dAT7unObwwbtJojEezWu3esbh1TEKIfZRR2vY/xJLsLcn
FB1wZr0rq3my1B4IMnnQIIIfS+isNYLyUxBM6cZJxcLfW7FBP3n5ut4fnHjgq+dL
rO25qX6o6PAs5j3+/Bjs/c4NhYhhKd59fHbRbrE6YV6XX85RgLgPf6lKbazDGaDg
aX6BD8/gxjZXs80eN+nEVfyUS+VDlwI8QxRpIAs6s3FJ8g84qqo3Bi45cjQRUcl3
0TE/AlayKAK+BP22XMZfCO1LN8KSO/1mUXlbj1eWJkCuiJmY1NaQyid2NLWtWtc8
QwS34Qs7OmGYaKm7FvDhflOmPuj3jgreNmXUQCPZmkEwXj15sr/hgkgv7DOXkqtH
Pv76HGbZjLD1ywcCAwEAAaNCMEAwHQYDVR0OBBYEFOitNMCTz/jVd9CIPHAlpD9D
VomhMB8GA1UdIwQYMBaAFNVmKiwSu16jTsYiNfN2oyxpsY9tMA0GCSqGSIb3DQEB
CwUAA4ICAQB0YDLjCyueHMq/HemqJhqcWLmccyPzNYuGxDTbDp6Rz3pfuSi2+UBz
oz9swcBer+3dbcxlOD05g/SReiyT2J15YZnsWd49ul1MYDQvi6YpnGP8OG3jT8E2
YTH55nWaAGpM6POdhmeEdSYC3sb13GArKHJAJqbumrdXUm3kjQwPrFrfsqWo3FGl
cjl2+2XXcfS388KYfw9XuacAeKrtBNpGuLVzvNvOWqo5YWfsgWnS6VI5x7gKcjrJ
sIFv3E3y6VR3TLG5D2GsHE9gS3TeMSaYtySl+NzlmfUaUBYdLyz6gPbO2ph9WdzO
0bVAtpZef6nuIBpWuVxOKTfgZKVPJly61iJZC2vFfKUUXduRbmhdcCWfKIw/VGeD
sX12oSMo2RvOBi6GMYj9z/1ZuzVPGm3muFYVtGfCr6ggbKHTnsQj+qwCnWrPQsub
olrascGR2mYXO5Tn+j1KswJElwZJvz/jvATxCVwITtn9K6yqwLAHJ8ZtlQzzDV4s
WcasX1msLGDZsJ9zwT1e6hudoGe1G58Bd2JKC73ZWqMJZVk9mTElfwZxcn7yMCv+
jL+RvWjPMrKQ50b/odpo1/y8PSS4Es4v39YKNzkfQ2FAOtZo3+2tKz+tN3Qqli0/
V3PQ3IzTk+WDwLgzzSxohNYl7GC75c4EC1qx+bGM/ryj6VIXjWBWxQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEbDCCAlQCAQAwJzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDzANBgNVBEEMBlNF
UlZFUjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKPTecIY0swx45cW
9KvwI2EZY7E/dAhUlHPOK72JpIGhwLTkNGIxri124wnioJpN6n4NvNk96olbWbI2
GeX8xTjf6tqTbrXIX4OyN9u4ikzCm9RCm4E8VwjXp+oGbh6dUMZHnWiqYWf0U/zJ
PzFNofo8oXbz0q9bMlQGntzPrvP1gKJYkf1Lbds10W2L+uH1ZyoG4pQbbt+uD5q+
W3nZHO9C1+Q7iVCL2Jp++kqRVy30zBezYH5Lr2UycSE4Z3HeHVyoHV3Rm5rS1LFi
a45dpwZ2xNIq+1PIfaYttC5GRQGS8BovHQE+7pzm8MG7SaIxHs1rt3rG4dUxCiH2
UUdr2P8SS7C3JxQdcGa9K6t5stQeCDJ50CCCH0vorDWC8lMQTOnGScXC31uxQT95
+breH5x44KvnS6ztual+qOjwLOY9/vwY7P3ODYWIYSnefXx20W6xOmFel1/OUYC4
D3+pSm2swxmg4Gl+gQ/P4MY2V7PNHjfpxFX8lEvlQ5cCPEMUaSALOrNxSfIPOKqq
NwYuOXI0EVHJd9ExPwJWsigCvgT9tlzGXwjtSzfCkjv9ZlF5W49XliZAroiZmNTW
kMondjS1rVrXPEMEt+ELOzphmGipuxbw4X5Tpj7o944K3jZl1EAj2ZpBMF49ebK/
4YJIL+wzl5KrRz7++hxm2Yyw9csHAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEA
eYzSOqlm8wzB76yDNwIxzam0Kpufzn6FlrgE0Wj2DmpvbCXT3jzApaSUXCbBqEe9
9iMqQ7jHvVc8bpZa2KXSYYWsq4RShraReAJG8FA+vuILVCKbwN6lDETvt0Ik/5kI
shNH8nYqdcmnuvMJrgeAzU+BBrguAXQN6IL3FX+yvAph/MHcLA+VZB+Mfpf6HJ7w
pmRc+6B919llu8JR6DewXbqaxFd6bhYQafeHAARYXvP83Qk78Qdg472zURoWaDsr
s8Y1rYL79Mc6CHPm9CdTxwIHl7U4qqAzuW6wOJzXDEr9/N4ujBISeE/b0Rlr1KPP
u+FnCk45KZb52lYDvIzZbtUxfLlWRWFix/1n/5x5JpJXThIWPV3GscOoWFraBkNe
4GbfXcl+TY6HHyf5ghL16cHNp7417tB0n6HezB+5tvHobfx9/TKMHckBdnj8ZcPN
df1nDdEleImzbVTBEI4kne0PvdvanbFNMKUPQ4UXWbLyIYNWH1376xOIS0TOVqZz
UDPpIZrFEidJzrVODyj8Miwxq+c/CekReyeaVhCDZBlQ2ek2GtK78GpkC2ACGd+J
I5E5IcLaDMg2nB4FwDHvgjwilXZdTqwSyQFkVLLV+gE/meSSfN52v7NgxFGMaR26
4UtJ68JWEkj56wzRrInMzOoMUUgm+Pm4Mk2c4BcdmIY=
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
F+3k0JHCVQEeL4cEA/KpAw6UnU2d6w==
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFTCCAv2gAwIBAgIUXQ4FoRH0FvD5H2xNaaDTwfg5PUEwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE4MjMzOTAzWhcNMjkwNDE3MjMzOTAz
WjA4MRQwEgYDVQQLDAtNU0cgU0VSVklDRTEPMA0GA1UEQQwGU0VSVkVSMQ8wDQYD
VQQDDAZTRVJWRVIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCZqzE2
HpjGV5CA5SLSgvtfL6/Uvz92KPO1PntzCNY7HIIpdahOloHQDCwIEpKp55vztpEp
BI5VRo9toJKuuoz/Bv/a6Yntn3TGphTDwxJpIQ/nrk9DgJxSCkjUy9ZAiRqx41ti
JOXhm0V3z2Ng84xKeguPU4ns41A96DeLsqMAe7s9OA436trxyjpbm4KyafNEyV1S
zAEmDIhglxSL/1GC5DrJ/lsC6BPhn3orhBwBXPhWekAQjl5A5vyb6lsTWqSd+Jw6
2cL7M+xtjxjTpbwYlKh0aPuhLQ1u8XpDmRdSV2MxRGWhgmPaSsgr9lZBaNunPOP8
OF5FLvBhweQcWR9ryFXPPPJOsQkjc5tXQstvIZmXNYNj+wqgI9SjhmXVhSE7uHgK
unFomhFupCLIdvc5rdHGf2VmPP3wqj3csJZ+JWkSLvoc7hYX6wUHvc9xlznHwCY2
/QnnQjFQnY0ieuufkx9cOfVDIdpdq9ChDbz8L0Be192p9yoCfoJg+s6nXiC59Weo
egRGiP9fwY1h+Tjnij7wNu2+4/0pZnBYMfB5HGaZehkfekJJBIeEPMqWOi29pQsG
NXafwZsBD8Tna5SBzzRWHK7N3KlDLMAcAaggqDq29Qe3Qxi4MqrC8sDb3nqvuIfC
EiUFxViuxiHEu3RNwXNOlRUKf861F5BUeOv/yQIDAQABo0IwQDAdBgNVHQ4EFgQU
RvyyWBnbGQDCdo3r9B+j3fhh8mMwHwYDVR0jBBgwFoAUq2bQt25dfiqR4TwnxHZx
vNttxzowDQYJKoZIhvcNAQELBQADggIBAAvVheyMER0LgJuxBaMfioCHP41bwThj
v8DaIz/XtNjTOXiBaeqOtdbfNld2Ix/AO2NXGHzKORrmk2WExgIdYHqKdLkabL+7
6T6mI1Kpd0y+eV9v32qdlUcvxPSmcRoInzDcHm8J9bUBtA56TEKB69AqtiIE77uh
luUQOnSE8ex8gNkTBpEb0TmMHCnEHhxDgjUViomT+PUlZUw+lw3e4S21xz+DsKtw
KwIsJTo068ocjUobZU1c2gyCwhC2QJ7aXnvSOdmJPPORhT90NL+bxXI7sfqdzUwz
Mcgi/sNqY2psHUo/TelaBlktjMl1M0UmSpXCGTLZWJANkrmz2CMu0ggJgYmTpEvc
DsuMGoirP6Dt7PXw4T3aL4sB5T5zYF/ZG0hxC63FEwLyhcoCb6LzuzSQkhMvOfdN
PMS4N2VdzB7tJzfVHUQR/sjyFv1cAlGxJOBJ6y2sj5FFtbv6grfcKwdBo+F+eJ9I
aWAjdiT9TAIii9Trgs6HBrpJW7IHVNBBKbhVwet3bUSiiPuHkDwDbf54WdS6WkV3
xjveSJkfC7OxThTiW+1uc8+1OsfVMI9pMEh8c53pCemAOkhpv8Ftkb/wxIToRIs8
uPwNtn0/jlYV2Kr0omCOml5crGCd3vIxq/bRiCaTu6l7FuY0dY4aYskwJFFtvwV4
Ew1HJZjVMjj/
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEfTCCAmUCAQAwODEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDzANBgNVBEEMBlNF
UlZFUjEPMA0GA1UEAwwGU0VSVkVSMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAmasxNh6YxleQgOUi0oL7Xy+v1L8/dijztT57cwjWOxyCKXWoTpaB0Aws
CBKSqeeb87aRKQSOVUaPbaCSrrqM/wb/2umJ7Z90xqYUw8MSaSEP565PQ4CcUgpI
1MvWQIkaseNbYiTl4ZtFd89jYPOMSnoLj1OJ7ONQPeg3i7KjAHu7PTgON+ra8co6
W5uCsmnzRMldUswBJgyIYJcUi/9RguQ6yf5bAugT4Z96K4QcAVz4VnpAEI5eQOb8
m+pbE1qknficOtnC+zPsbY8Y06W8GJSodGj7oS0NbvF6Q5kXUldjMURloYJj2krI
K/ZWQWjbpzzj/DheRS7wYcHkHFkfa8hVzzzyTrEJI3ObV0LLbyGZlzWDY/sKoCPU
o4Zl1YUhO7h4CrpxaJoRbqQiyHb3Oa3Rxn9lZjz98Ko93LCWfiVpEi76HO4WF+sF
B73PcZc5x8AmNv0J50IxUJ2NInrrn5MfXDn1QyHaXavQoQ28/C9AXtfdqfcqAn6C
YPrOp14gufVnqHoERoj/X8GNYfk454o+8DbtvuP9KWZwWDHweRxmmXoZH3pCSQSH
hDzKljotvaULBjV2n8GbAQ/E52uUgc80VhyuzdypQyzAHAGoIKg6tvUHt0MYuDKq
wvLA2956r7iHwhIlBcVYrsYhxLt0TcFzTpUVCn/OtReQVHjr/8kCAwEAAaAAMA0G
CSqGSIb3DQEBCwUAA4ICAQAEvbrx5s/1WkhMdeqSbiqwEg2J62kpnDse4/gqZQYw
wzYTvTXQ0ih111FHU9hVf6zQwet3qcmemwIVNo89WAlXJCnLYsKwvx0xTslCP6/R
G7/aQUJd+2e769MGOrx+UbZ4ekP2nNRBHjSMIV+FEwbhgssfGLEZilitOcuvdPXq
kNFoRkyLJjlPGLz5+xDiJ/+ewRa/TmIYBiW38+goNYuYh/UXDV23+psZd5lFzvFQ
HPjtPlLUQf9pKYYfHVt8XsJpxcCHK1NcRkX6N62j81QvI4mm33XZb5eNWKVfLE51
t61RbnQELLwjIXi/lWOjkoa9dwp5V5D+0QnCg1uvWNFOnpeSg7GbRieMPW9UFZv4
97OJlZ3J7UiXGlc9f66ZsPWekjiZI6U7ghke7WUdyQ4SWOSCC9vIENUG+FUTsmIX
emTnZl6nRcA9KA7bADxIruqjwKeycENZVAsyiSwFv14fLtkBQNhG9SuZjSxNvgNV
weAEHaF2l7WiVqS5J6PywqPEAH04Rza/4+aMYg+40l79aKyBGrAImpulSVP8fn9A
VWj8DesElx3WO/93lCv2z8QwYnzSPVsBJhmrWiR+8Xuxrmw1z4+KXR+W95ztIUr+
Kq9zCJguzxCoiQPZMpw9FqoMkjQeteDUmZI4OqOhwByTQBrgBFFPoo/Q/QTI8gKf
Ng==
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCZqzE2HpjGV5CA
5SLSgvtfL6/Uvz92KPO1PntzCNY7HIIpdahOloHQDCwIEpKp55vztpEpBI5VRo9t
oJKuuoz/Bv/a6Yntn3TGphTDwxJpIQ/nrk9DgJxSCkjUy9ZAiRqx41tiJOXhm0V3
z2Ng84xKeguPU4ns41A96DeLsqMAe7s9OA436trxyjpbm4KyafNEyV1SzAEmDIhg
lxSL/1GC5DrJ/lsC6BPhn3orhBwBXPhWekAQjl5A5vyb6lsTWqSd+Jw62cL7M+xt
jxjTpbwYlKh0aPuhLQ1u8XpDmRdSV2MxRGWhgmPaSsgr9lZBaNunPOP8OF5FLvBh
weQcWR9ryFXPPPJOsQkjc5tXQstvIZmXNYNj+wqgI9SjhmXVhSE7uHgKunFomhFu
pCLIdvc5rdHGf2VmPP3wqj3csJZ+JWkSLvoc7hYX6wUHvc9xlznHwCY2/QnnQjFQ
nY0ieuufkx9cOfVDIdpdq9ChDbz8L0Be192p9yoCfoJg+s6nXiC59WeoegRGiP9f
wY1h+Tjnij7wNu2+4/0pZnBYMfB5HGaZehkfekJJBIeEPMqWOi29pQsGNXafwZsB
D8Tna5SBzzRWHK7N3KlDLMAcAaggqDq29Qe3Qxi4MqrC8sDb3nqvuIfCEiUFxViu
xiHEu3RNwXNOlRUKf861F5BUeOv/yQIDAQABAoICAAIdIjyp2BUmYDT9sehuZ9HL
4KHPDars7klIdj9DWFsQzdOPLEUEef2oJTTpOH5A0trb4IxNZT3UDiYGZu4jX8wk
RwG2Y7DSmDMhVrjIpqiujT71HV8C1mOkg5L1yNkzaZwX0gp8EnNzhNWckzPitcPS
gPU0Q3nwOIrZdmYkC2z2xsEVU9C+GMvpqbrX3Ujh/zgrgu6gIsXotzmI6n3wgakI
xaxApPTZx2g7nt0ZYJ8+LaZW4Sm5I5/F7aShaSZPgWMw58lBdJarBK4PIVrL9VXr
OZP8W7XAXmZvyOxEH1eBHzquw60gk4oNrEo6hb45mIfo5QPzrIxMFH9rwN0I9s8p
yYLoWIzvkm2yOLRD7FlXCIwvFvKMkyHFZNdFgHldt1K3m0vzvtkiOHx7j0cwMZR5
KsDebslREb1BPKi7GhwyKn5EcBPrTacracSEBHZgvb2Y29jK/2E4oJNoHt373oFy
/8mI4F7yUsZBBaHSpJoXIkSGtjkNbYAj+EctJ7BX3ywYVSsufipypCYD4l9H56TB
j69KdS8fVx7H+Q/MZHfrZC9sDD+gvwL8KuJvV1ohiLwNkLuX8CiQbXjgyP4Xd8ij
/2qlb2kAisbLcCGLxdTmWFvl8/ckrEHzGoiY4V/wiT165xmDshYSwcD8Z9l2SlTg
V8RLJ8vah2fxkrBX50/vAoIBAQDLGVEHIMvNHsCp7UF79YSmqLOCL2Ovc2a/GJ7f
jyN1E7W2/ANbAw8aQGd641YFyyR9SPF6E8a/szIr4OpEE/EyQD10HPkp80I9/RW2
LKj6yrYMzHJXNg6Rn8OEGRbRoIDvAOuMqHCavtCGRjvl7wY3YLOS4NqOS0Cj8xLO
VCijpkUgDc13bc/lNtXssgVjWXzpTIVKPC3IPKhjf9nTj8k0dtyU5tQdRs8ETHiL
SXnr2z4Ik708Jj7G+JP8T3+NQ7j5CVDc2EdXCtu4uDmx8HMEiB59F9fl36OXi4dc
SeC1CfnYAv9IDollxDSymJcj02XxUTs/Ws9PySKQ/qKtouwnAoIBAQDBsdwabVTa
KDcn2EIumDguBEeej5h/XTIlF9X7rSGb/zOskrrUoDiKAWMnnKlBrD+SuWGInIVD
WJEQofYKlcao2Ol6uvY4+D8nA7TAypG/L8ock/BsapKwV5yFJIEEKsxuGOSh99LB
r1YdMh/J1NoSdx9HC+13w3oEd/pr16NX75qZpGTVDb+IfqlXzLC0R3I83SltxACP
ZrwNEKW2MOQyTqMhNTnmhtc8CyrduOs2FLXDtv3QonIihah+scjbFdRmRGUhuJWW
AozgYwsWrI3tLDVGI4cm3uKGQUCU6TBKMBo4YpDeXPnu5Hze5+uHgDOVc9ILKNXc
CNiHzzKw1PqPAoIBAEuPSaP7QZc4f7k4eYpil01hqhcfBlk599nUkRbfK/Pct1gy
fhUYGEBOAbGoblKNdy/dOWmPffvH8Tx92uok+TEW0UYnmVNQGy7wv2kdSGi1jfFJ
BqkHhXgMFjNJGkI3EoDYuMmFyQ7pOq8Z5iLvQELOCUD1wpn5yTy1rCNzEAOCUmlQ
eUabZiMCuafruzFxE5XAUD6EEQxT9Nm/sQySi+qm5f3HutaBh3cz9Azt8xwaXwPV
4ytDl0tzI6tU8EFgFqsgGiNvm2r4sTIR5/UZXdEryxwDCOGOyFATKvLc0WrJIViK
FOt77QYdbvWa62/6sAyNihtR75rhW6jR8zfiSzUCggEATR4wYQE4sGcklqOergiD
Dac8kJ/heowzg9s6oiqrX/26qDH/WtqzyBaHUOUp6nDXGubeM1MGJ+siTrn9SPeb
EezTAL9hewszsafjFoNQhgtT8A7iwXepEbbAJa6EA5G6tPcKSIZwDhduNM+ZInWx
oXp2JIZWNMHKWe8e8EL50PAf4J44Wy9PG9w6Ni/UBuMPU7ZGYWKRSob/xj/jimdq
47C1eGpFtEfpeAmGNqMCWxThzZuU8LVMtfv7Ov4z1y6Y02LV1Rg1znUTe99TMeLf
2xcn2tYYYFyLWiKuwNsbE96VAfAUd8QS6o9kPCegeeGMKCvl6/WFOEb5VxEiwI77
dwKCAQAfFXOYeT7D3MgG1KMqW0PjF5GMLAgp1aNZbARC1HzO7avu/kEjtxPrOWTi
T4K80tIhynG/SAn6rEgxEQ2ye2kQcuPFwEM4W8OUma7okCXrhKDZtXS3aBAMCM9C
RMk6w4k8AIsnzWz690TxPsw9jyw/vq+hOJuQzpynNq+hvEXJIikvVpNPL2lZHAp2
KZInHb4NFRV9LBbsOyv5YokklwXYRahheB71hpCX92u8jLWTguixxoLg+7uU90Ax
J9YlKcbrXlfAN1g7396TccF47Tk028fKKnIOEAZ0PqMa3YHiAfszCNVuMtQBrhHD
Tx9Uz+kmck7CaSadegf/5xLCVin3
-----END PRIVATE KEY-----

Binary file not shown.

48
Projs/PD2/certs/README.md Normal file
View file

@ -0,0 +1,48 @@
# Generating keys
1. Generate CA key and certificate:
```bash
openssl genrsa -aes256 -out CA/CA.key 4096
openssl req -x509 -new -nodes -key CA/CA.key -sha256 -days 18250 -out CA/CA.pem -subj "/2.5.4.3=CA"
```
The CA passphrase is 1234
2. Generate server key and CSR:
```bash
openssl genrsa -out server/server.key 4096
openssl req -new -key server/server.key -out server/server.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=SERVER"
```
3. Sign the server CSR with CA:
```bash
openssl x509 -req -in server/server.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out server/server.crt -days 1825 -sha256
```
4. Generate the server's keystore:
```bash
openssl pkcs12 -export -out server/server.p12 -inkey server/server.key -in server/server.crt -certfile CA/CA.pem -name "ServerKeyStore"
```
The passphrase used for the keystore is server
5. Generate each client's key and CSR:
```bash
openssl genrsa -out client{NUM}/client{NUM}.key 4096
openssl req -new -key client{NUM}/client{NUM}.key -out client{NUM}/client{NUM}.csr -subj "/2.5.4.11=MSG SERVICE/2.5.4.65=CL{NUM}/2.5.4.3=Client {NUM}"
```
6. Sign the client CSR with CA:
```bash
openssl x509 -req -in client/client.csr -CA CA/CA.pem -CAkey CA/CA.key -CAcreateserial -out client/client.crt -days 1825 -sha256
```
7. Generate the client's keystore:
```bash
openssl pkcs12 -export -out client{NUM}/client{NUM}.p12 -inkey client{NUM}/client{NUM}.key -in client{NUM}/client{NUM}.crt -certfile CA/CA.pem -name "Client{NUM}KeyStore"
```
The passphrase used for the keystore is client{NUM}

View file

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUfEdbWdFRD1TgQr9L/b6BG/TtrzUwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyMDI4WhcNMjkwNDE4MDAyMDI4
WjA3MRQwEgYDVQQLDAtNU0cgU0VSVklDRTEMMAoGA1UEQQwDQ0wxMREwDwYDVQQD
DAhDbGllbnQgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKPqlFVk
jPsXRitfIlY10cfUH4Dd3E4i+lL+AuiTP49BWpYPa6Z0lXlcNnR4vpxhVbZyraHP
qlg+/THqi7KQzQkeNxh+ep5IXguBPsWksOsB/LePS++bvtkYMIB4LA8K0HmUcoZA
3hgblK3fDiSh4e4shNHKNyef079Va7Fww9hIwAk1vTylNqvmbtHEF7rvbQGYjsmh
TbFO8dOToI2lNcx0M8q3v2D+ht2NKJfAD3EA1Zqd52/HqABiSmG/6cD624qE9+Vf
uoxoXsx3fGYtnwFE29Ia2b/MZPTgq9MUTwr15iZLhKmZ7pl1/7yVGzulPkaNUutm
zYv4lv76KeMax4PlTwWk6PnnjZewCJMZFLrlUvW071elitkVhC9iMewa0WuczkUL
Te0REYWDPAhIIuCGRpt74HRiWxq5sq9q50w5NIKpgE0WEKahoNz7xpLwUNP514jZ
Tx9rAxHk2xzGn2xuoNoW+WROWuyYizozgaxhqNqEt6UXOk5ptcQ4v76KxcNeZ+iA
cKydGzEm377NLoGlPe1eRhQVXZ3sKRZS7+Wlr1gMP+gQGDfMNetk3LP0P5nZ82eN
dep74VwjX4ZPOrUhQ9IT0VpKmxpRo+Z82eupr+aVJr+5gvrIrSFAzG56iguz0vYr
t3NoT3i5BC04W82XcR3MejDXs0iPsp0HlEK1AgMBAAGjQjBAMB0GA1UdDgQWBBRJ
MH7dvIzSSdQerDiVwC7aAtfMOTAfBgNVHSMEGDAWgBTFRNY8++1sHgvGqO21WMbo
wnWw0TANBgkqhkiG9w0BAQsFAAOCAgEALD+u8ieLA9tcZVoX9rhfOxXoqxxvRzKi
rHkHV1Oa0Ju6T/mnvkFafwjOUGHo1prTW6MyL1re1l1xVJmgas9RigsbztBl/5n5
l/5RCK+kjgABH/jutJhHaU6CHxhyuzeQUzCuYtALOMWzRVm53P5mQXuFhwGxB64o
oDfyMoYn44Jjpb/dWkY+k49vprXwfaMf+JtzeOSAeqfqt6AHKoNRb1fVc3E132k+
hBTnhYgDjquQNJOhKKkACAwMPTtC21F+MObRx9CxJRR78y5jF82YsTdzKtWwliCC
j6A3Wl3TzVpiNc6ifsnqGA/49UKOh108gt8+yJx9fQFduzaPt7mV19zTSoqq3Q9/
2awep4ObDwUY3jqFLXYBPcr27fh7ygHFTqbFieK0nH52IMv3ZxRs94wBbmHykxPq
3ka+XryMVc9Ld+P9AIHeMyXdkqGNP0SrkolSfgNigO/l/NSdcn4qibduZG9IlUys
S1JztvWHjrYYeE4he7eVz2BdKpjmAJtaM1zWytyCYVXqUrbw+wN0JC75LD3bcW8J
cjK1IcsQSrFeLiwtfrQp8K2Saxa43t3D6iCceji+8tV3YTrIfi85F3sq+Crrej3a
vtRJAiSKH3UKk9TBv/MvHrMkkTyId8HSdngRcj4KqBahluoo9lPDQGwaXfXAeSI1
xNijtO4t6eM=
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEfDCCAmQCAQAwNzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDDAKBgNVBEEMA0NM
MTERMA8GA1UEAwwIQ2xpZW50IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQCj6pRVZIz7F0YrXyJWNdHH1B+A3dxOIvpS/gLokz+PQVqWD2umdJV5XDZ0
eL6cYVW2cq2hz6pYPv0x6ouykM0JHjcYfnqeSF4LgT7FpLDrAfy3j0vvm77ZGDCA
eCwPCtB5lHKGQN4YG5St3w4koeHuLITRyjcnn9O/VWuxcMPYSMAJNb08pTar5m7R
xBe6720BmI7JoU2xTvHTk6CNpTXMdDPKt79g/obdjSiXwA9xANWanedvx6gAYkph
v+nA+tuKhPflX7qMaF7Md3xmLZ8BRNvSGtm/zGT04KvTFE8K9eYmS4Spme6Zdf+8
lRs7pT5GjVLrZs2L+Jb++injGseD5U8FpOj5542XsAiTGRS65VL1tO9XpYrZFYQv
YjHsGtFrnM5FC03tERGFgzwISCLghkabe+B0YlsaubKvaudMOTSCqYBNFhCmoaDc
+8aS8FDT+deI2U8fawMR5Nscxp9sbqDaFvlkTlrsmIs6M4GsYajahLelFzpOabXE
OL++isXDXmfogHCsnRsxJt++zS6BpT3tXkYUFV2d7CkWUu/lpa9YDD/oEBg3zDXr
ZNyz9D+Z2fNnjXXqe+FcI1+GTzq1IUPSE9FaSpsaUaPmfNnrqa/mlSa/uYL6yK0h
QMxueooLs9L2K7dzaE94uQQtOFvNl3EdzHow17NIj7KdB5RCtQIDAQABoAAwDQYJ
KoZIhvcNAQELBQADggIBAATwXmX8jOpyPeH6PiC0pXo06CGpBtEXkcNeBt2qWway
XKa83AJ8jZxE0GBuFtqLYW4snI1IleEfhWQKEweVXYoBWeWfWj8EeGOx3+ow35Cg
IkSNJ96zl63L1N3DURqHfU0gCHB2/kY4h6XjawOolQtOPShPEW4oB8jj2txmgmzR
Cd74KzACymNdS+LzSFDp9rZkWWOZS6XOaqZ47DndveYc8GvdubsChZbUApnHOWw4
IYcqRAaMGOXVKino9RTp/3TLUSyIVdxJKSzBqEKFRAgElns5bixCtr1PpnpCyE3h
mCtU4It9nqZU2zi++elgun4yIHLvZW5bZtyKJvQhgSKoX24fx/YzZUY4doMcsttD
I6FiWLyxuX0qMUpwMoz156yFhLFisFm+Xz14KhIJ2ZFxWKkAz8LqV9qS1JHFiwax
wiR9qXHwBtCPneQFLjdR4Thk9f1bFJC0xXPMbWOPch8+FRlN/1dhxqmgfYNEw8sB
Y94QtwmGplrjgatWE7J+Hy1NR9Q9UHhTxB4mEQ6sp5OoRtHl1qVBW+Y7Tbsg0Fp8
U+dPvR17o7KA4GlHGC4O+lN0u2tZyg+RAz/SdSBMppjkMbN0WFtBRMaDjJc0dT9t
fmPSVBrK2kjlsTp4GPCQL+W5XhIgCv59muMUqexv/Hx7pRyAZxG5VPxij+j3blC1
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
V9adr9w9IqxWjYWPMhfeyCbQgFcWoA==
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUfEdbWdFRD1TgQr9L/b6BG/TtrzYwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyMDQwWhcNMjkwNDE4MDAyMDQw
WjA3MRQwEgYDVQQLDAtNU0cgU0VSVklDRTEMMAoGA1UEQQwDQ0wyMREwDwYDVQQD
DAhDbGllbnQgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALHS8R5G
1AJiNHR/vsc3V09Xd+rv9UhC3TA+ITxG2rjmRY7R1etFVtRFhE1o0DLklkFIBo/L
O8nQmRmu0iS/tlIS9mZqAuqz3am8nbYH5F7WXstFMLV1CwL+AIegcqj0sMFD3Ccw
q34hY9ta0gATP+aDcgOR77zZCaRjExCFnmDxzsvUV7xaqrqU7i2C99yqvSr1dGRt
pAFZgpyxYro8JE3pzOfkbQNrQ7cftR7ldAhWFJA8sJsM7hUlu19SCGbkaCiLJPcY
0yLcfwFAhiz4zUpA/CGh2sSAHknHUdkJBee3ufoZnhCDbkmlE58rcodsSaK41xHA
I2UrI+PFuQtdAfqDS8OFLKu0dj0E8mAA9/GTBlLdIw3wgIy8pZTLRAK1/8UcKfKb
4lNqXWDp9ZKH/pWwTqQ2Fmke95+bNoyOTiDNxEDyyYKu77uclqaMo4M05wX+3wVW
5y7XfzcBF1oi9R9SRHzWlaMj1otaXjjzb0SJQNBB7V3MT4+FXe7locQYvVU88Gtg
GNcqb9IKS15r5ki5VSrn8nnAC9yPs97gR2m7BCLRlPmLvT2ao+mUJzthhQfAyMw7
nSZCJ7fUboXYGL38bcEd2AA9Tms2x5Gn5G7yCBDxdFkhj2q9sEv9Eb6XQB77Uxqn
sKo9OenkOv4/CEkfo4urSQRhGQk5w4nbP/CvAgMBAAGjQjBAMB0GA1UdDgQWBBSH
7YpbUnl1vZcJ0JC3HwV8apJDLzAfBgNVHSMEGDAWgBTFRNY8++1sHgvGqO21WMbo
wnWw0TANBgkqhkiG9w0BAQsFAAOCAgEASrKbLxTdR1+SLyMKl5AxRO+4uvtMzYD3
4VmXtnr1gjoEmX79c6WfTrK2o5fh01MnO4Gz7Gz35pQUDVMOB0xvSriF9KpO7fMz
yCq12M1TjDtSHuzxbRDb9i5gmbF/LBCszq1XouV5ltZJPMHIzKSwHjE9p66ZTUp3
JWbv+PQHaATzY6XVTDf3a0WFwEAl8A/spnx+HtdV0oHAeg0+BmpmMLSycw066tyA
SE1ixiDPMKkpjiK4K1KOdxIuLIHT8BuHV3qebaO7G7X+byv6VmeX9/sxCRQ+UfTX
pA4oRkP3eTF51V+yccb4xjW9dGPbHE9qB2RCdbORQkZ9Q5q8174mSkTpBYUVsEK6
/3Tme5jSR17D9n9nwRXin4tg9+sDd4nNns378MipZD+HVlpY0kt6kKeGDSfPe3N6
6ZDYdHGDZSHFAjgVRpHj2dTqm/vENIELJYCRAADhApHhFGpxPuYOePFg42mIst51
WCXSLEXcGIX+W7FCV1otkXxroYAapZVRVsfbk6ltAmawY4cGtz/pItgvc2e7W/87
a5yoUtD2eoX+YbQ0mtfFjIwg+sD2imXPBatLBcngaLPF+3afwvXc8IcR9qx/FgwL
nK7IKVBsPt3P7Nr3de1nXrui0yVZn1yXO9SKe89O41dwP05fQaZQAGGUWr/YntqB
JO+V/TUhWIQ=
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEfDCCAmQCAQAwNzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDDAKBgNVBEEMA0NM
MjERMA8GA1UEAwwIQ2xpZW50IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQCx0vEeRtQCYjR0f77HN1dPV3fq7/VIQt0wPiE8Rtq45kWO0dXrRVbURYRN
aNAy5JZBSAaPyzvJ0JkZrtIkv7ZSEvZmagLqs92pvJ22B+Re1l7LRTC1dQsC/gCH
oHKo9LDBQ9wnMKt+IWPbWtIAEz/mg3IDke+82QmkYxMQhZ5g8c7L1Fe8Wqq6lO4t
gvfcqr0q9XRkbaQBWYKcsWK6PCRN6czn5G0Da0O3H7Ue5XQIVhSQPLCbDO4VJbtf
Ughm5GgoiyT3GNMi3H8BQIYs+M1KQPwhodrEgB5Jx1HZCQXnt7n6GZ4Qg25JpROf
K3KHbEmiuNcRwCNlKyPjxbkLXQH6g0vDhSyrtHY9BPJgAPfxkwZS3SMN8ICMvKWU
y0QCtf/FHCnym+JTal1g6fWSh/6VsE6kNhZpHvefmzaMjk4gzcRA8smCru+7nJam
jKODNOcF/t8FVucu1383ARdaIvUfUkR81pWjI9aLWl44829EiUDQQe1dzE+PhV3u
5aHEGL1VPPBrYBjXKm/SCktea+ZIuVUq5/J5wAvcj7Pe4EdpuwQi0ZT5i709mqPp
lCc7YYUHwMjMO50mQie31G6F2Bi9/G3BHdgAPU5rNseRp+Ru8ggQ8XRZIY9qvbBL
/RG+l0Ae+1Map7CqPTnp5Dr+PwhJH6OLq0kEYRkJOcOJ2z/wrwIDAQABoAAwDQYJ
KoZIhvcNAQELBQADggIBABejmbhpgmP0/2z8pOYhJutaRiytES1q35dyZsY78rSM
zrq/emZnPs/L1cTJf6JlzpO12x22bThULoYvlW2x4//mGg6cQxyUOi3+VwyoTZww
qTeNbyxySIOQWXJfFZNf0Q5LLpKdoK7z7MeiEG+T0LlJskv+kcjaE9D7ldPUaGuq
TqKQuDMourUE24bXQ6GcGv/FdFf3zx9TuEJNpw9kp5vCcSVoKFicggmY6BPssRxx
XcHNKIzWG0YgCoOHL6HT9WlYp2vbDiLHk8vZ6P51a4R97X55WZ+jpCZllyvcSm8B
UEiZzTbH7wEhg3EBddyv0uHEwpnzKzj34ekvO/i23jJ4rSVAy6kTES1577/BKmgg
ZhXYXyXhEwMLzopqSGsRiDfRBk4hJP0sjOz9V0Git3pVzvoDFNxVu4sa+PhaNEnV
GO64lui+4h9GiuGed7z14178+YwbcKd5H3QuW4glATxht5Te2urD8ahChpK6Tg+Z
4ZHKKUjgqxwQKI0AtZDZ3+WzGkyELvLNydzNw7/lrAQPPsnXy3UZTM8tfMCK6XT0
oAHeYwP7isf0gMvl87voqV8ILIepZuWKbHIJzWT0Lrku8yjPE+6vdJQgYbtwE1Uh
P/rV5A8FY1ZzXOMTz041Ky/DmAte775MzSM6JzAPtNee1CdFn1ek/CVvFGmf7hxU
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
QRaur6QnOTsf+omdCjplByBOrr6Zsug=
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFDCCAvygAwIBAgIUfEdbWdFRD1TgQr9L/b6BG/TtrzcwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyMDQ5WhcNMjkwNDE4MDAyMDQ5
WjA3MRQwEgYDVQQLDAtNU0cgU0VSVklDRTEMMAoGA1UEQQwDQ0wzMREwDwYDVQQD
DAhDbGllbnQgMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVWtrDZ
80/MZn6NqfVwuWK0Eam052bp0k8kHvf0MX8nw/7CzVuVw6cljRrb9L1KBAatdUfN
se7uihmcRq1swR7bepMTseNPnfAvc5pVhrZP/NWyxV2MoPWKV2Hb0GYQIen85OSw
XVYmRAuqls/d40vaCoWbqSjl5URNUBZGYKP3dpBeH397UxpsUas2sDG5gLZzonoz
UYzXUicFB84KKiipJbEYYpykKOI85o8VLw7xhLBXEGxavVr3f/XjJuG6OklSuaJ/
1yTL3uazPUYbWmZKH+AUGY4Y2CQuOFQYzev43PPkqksrAGLdXubTlJWOzTcW/zCi
BuOlMXZEWeOvhROVzS7msJnjLPdceFhbrQCmdyMjfg70U4fyr1S6mpC7nGVozvoS
mJN60yFpJHk/5sn2FhYDh/OGiUOhZbszM3y03aUmzFnPKGEuCfUg03YURsHTyWvQ
NUsG4WmpjZgyF+xbwPBBthCoeQAhkBe3PRlmlx28hKV1AuEcbCjNuxy1Phufz4Ng
+IQXLuAzPl9N1C9j0cQYBuv3/k1IMQHyDqX7YDZ5/XTd8KcJeXXhe67GBZQIhHIy
sOgsXlsP4fuHEWKOx7PurVMaasr11lsRsWEdyzELIrRVpT92dbsRik2omjGdJfSr
iSMF7cpnmiWPgq6k0oXojKfFc+GYmxwjB1+bAgMBAAGjQjBAMB0GA1UdDgQWBBQ2
8dCxdfmOT0mXBVB+KPQBhFSYvDAfBgNVHSMEGDAWgBTFRNY8++1sHgvGqO21WMbo
wnWw0TANBgkqhkiG9w0BAQsFAAOCAgEAeJVgfZx/wTsKg0i8HwUAM+5eLonltGk+
Cbi8Lvl6ip0mq372ekEc0j6FXoRwGg4ULX6AgQYd7KBYpCixazPvTheRERrpnKX5
LJNx0Rjet9Gh7JBhBKTNnWYKKUe8yF0vL2KEABftX0JUW+w9FlLf8OTkjx5qVstw
hLbBxYa4G3todA0F1yzXbtsHXE1NlA9bdsxlnUr7PgGj7zN/lqYvQGjYv6ZU2QDw
P5RLTxOnNiV21l39G4ABhofSfDGmVDjgdN2avXroHyBQe/2gPdZBVK8HEzoOCxhb
dmEH/9/6Xh8TdYDGMPkuiI7cyUfGZj0HLznic+DZjhvm5JO//6KgzO6k+ZGlTJV9
HUvAveqyq69gubFtyL+Fxk8ZoxCFBdyXsZXQV1Rg/3tECqq4KKNwrY9z9IiZqeJ6
nPWuBJ7b8ZhK3hMhGbyY+YDo9he9RAnsOjHsXVi1rMXaOloZua12qg1E6y2X/xH/
mOZFj+69x70xdVUaDpRvmw7xpAEG0JRdUW7/WThWj+npn2S/s/75QxX/W9mS6Yta
e3dj2nqSP3JCOt+KIoZExmB8K/ho8laJRT9cKrTK+fiTkt7uw+iItWctucauKAEd
7KRU6Y87aWkbvmS1+ITfIu2bY/FBKRIKHVfG3did/loKcSbadStpOnA3X4f4/RRd
T/ClrFe6zmo=
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEfDCCAmQCAQAwNzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDDAKBgNVBEEMA0NM
MzERMA8GA1UEAwwIQ2xpZW50IDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQC1Vraw2fNPzGZ+jan1cLlitBGptOdm6dJPJB739DF/J8P+ws1blcOnJY0a
2/S9SgQGrXVHzbHu7ooZnEatbMEe23qTE7HjT53wL3OaVYa2T/zVssVdjKD1ildh
29BmECHp/OTksF1WJkQLqpbP3eNL2gqFm6ko5eVETVAWRmCj93aQXh9/e1MabFGr
NrAxuYC2c6J6M1GM11InBQfOCiooqSWxGGKcpCjiPOaPFS8O8YSwVxBsWr1a93/1
4ybhujpJUrmif9cky97msz1GG1pmSh/gFBmOGNgkLjhUGM3r+Nzz5KpLKwBi3V7m
05SVjs03Fv8wogbjpTF2RFnjr4UTlc0u5rCZ4yz3XHhYW60ApncjI34O9FOH8q9U
upqQu5xlaM76EpiTetMhaSR5P+bJ9hYWA4fzholDoWW7MzN8tN2lJsxZzyhhLgn1
INN2FEbB08lr0DVLBuFpqY2YMhfsW8DwQbYQqHkAIZAXtz0ZZpcdvISldQLhHGwo
zbsctT4bn8+DYPiEFy7gMz5fTdQvY9HEGAbr9/5NSDEB8g6l+2A2ef103fCnCXl1
4XuuxgWUCIRyMrDoLF5bD+H7hxFijsez7q1TGmrK9dZbEbFhHcsxCyK0VaU/dnW7
EYpNqJoxnSX0q4kjBe3KZ5olj4KupNKF6IynxXPhmJscIwdfmwIDAQABoAAwDQYJ
KoZIhvcNAQELBQADggIBAEjCzmAnwXNtoScpxX+z3siWA8Hy41BmI/lIL4Gk1stl
UpCSGbdjlJNE3Vr2jnw4Usz/MIRVLeAeaFVVKm+5ILZEsvhyk8ULiSLYxa7nlL5n
yexS0a+vvdnicT9ijoUGxuRjk/5/5dKZJgLGgSl549lvmlLKPA1sUDcpwz/4fw4l
jEqIwoceGVJpP7rBzznYltaFzZsqTwJ25ZGgIccEjGO9H8bBkrPFh+q3dPYKqwRj
OeeA+ewgWCDLL/ReTiZS77O9aUTK7xymZdHHmCX+Xy4KUkRr7eM0sIfnLYd9BSMq
aBGHn7v/3ZaFZ1qp2RRBugkJupu2mkmmdGM4SVa7uXAT7PdnWBxLMFWo86iGpeZu
85RMFcq3MeVbi5wYt7IuweRrTO5MbSglXSizFkexJxmaLMXwdrso0MVf6yaTSp1b
gqGUJ6zaRfBYFx7DIBUvdCl9bK3UIVIMv7NYzZ3v9plZQNM5UadbisGsj/BzOzmv
jgwNtoF4gKO1lKLzzlRepBWGe+e50dvCNhBuaxg93ZOX9D+m24k6r2JIBqRPG4OD
xod9DoRnq6ANtjkIJYN5kywlI9XrtGX5RGyDMrWWBqjAvSl5Rx9rg2jiOuiv5lOn
PWNFasLC+jhvTeL6S9PpFYDTR76QM+9Dfvn45+ph0zw/5Y1Z8oEH6X31sg6E11iG
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC1Vraw2fNPzGZ+
jan1cLlitBGptOdm6dJPJB739DF/J8P+ws1blcOnJY0a2/S9SgQGrXVHzbHu7ooZ
nEatbMEe23qTE7HjT53wL3OaVYa2T/zVssVdjKD1ildh29BmECHp/OTksF1WJkQL
qpbP3eNL2gqFm6ko5eVETVAWRmCj93aQXh9/e1MabFGrNrAxuYC2c6J6M1GM11In
BQfOCiooqSWxGGKcpCjiPOaPFS8O8YSwVxBsWr1a93/14ybhujpJUrmif9cky97m
sz1GG1pmSh/gFBmOGNgkLjhUGM3r+Nzz5KpLKwBi3V7m05SVjs03Fv8wogbjpTF2
RFnjr4UTlc0u5rCZ4yz3XHhYW60ApncjI34O9FOH8q9UupqQu5xlaM76EpiTetMh
aSR5P+bJ9hYWA4fzholDoWW7MzN8tN2lJsxZzyhhLgn1INN2FEbB08lr0DVLBuFp
qY2YMhfsW8DwQbYQqHkAIZAXtz0ZZpcdvISldQLhHGwozbsctT4bn8+DYPiEFy7g
Mz5fTdQvY9HEGAbr9/5NSDEB8g6l+2A2ef103fCnCXl14XuuxgWUCIRyMrDoLF5b
D+H7hxFijsez7q1TGmrK9dZbEbFhHcsxCyK0VaU/dnW7EYpNqJoxnSX0q4kjBe3K
Z5olj4KupNKF6IynxXPhmJscIwdfmwIDAQABAoICAA73yN2hJ9m62+zvQYueUdcJ
WPnikkUm4LKinyHFWL6PqDhjmPLJ0lv+F/8TD8j+DoYElE0od9rqeqCxiw3uj6Q9
5oi0U/cYz8cPC6I+FAABazOybWMS5AhQcnUD4VhDVaFMPBJ6UkH1p6E04/zlakkN
BthPaG+VRk7UeNtV1M1D9FfnRP9PTSU9sqIIwhNgpfSpZ8xhZwZSkZfh7Op/YUp4
58EN67nVPQCrmTZPP9KicdriXNssxDt5eWjw5nk0V3JM70Cv/7CsWUo+mjyqrlQK
I0ZqMk/N0i1uWTzrzTeAk7BX/Ax3ULFYZ2hzJ20O2/aDoe3AOgRZUtNZwfeuubOn
m6QRk0GaducK4clszNKgH8I47jHrKNFhatnihTLnxxgridXtMffrhPk37ou6IdCv
P9G+wzAsx5v06oloP0Lgx2Ln+2P70r3wl2YVkCX/uR/7hfj9YnjWbgH8X1mN9e6X
9Y1/4bywppIMpHNER79RJI6N0OIoSWLOW230+3wu66fe7B/aVuk4hIMSXcz/0RfA
9NH6rnbJ/agwygEG6vIyNSBrNefoXRNM5L8hkXPQKhdAoxWpUmB8TEdGLWFUdkmg
BH23iAS3YWX66ktk+edM+qDR+fZ4wws3pcuuLQTX06iSeDgcr/wlkp5W1gzRoYH3
95Dd6yal3l3kJPaMsQGBAoIBAQD9jorbL5afL1wtSImU1lBn3wxa5iwKhaBdQY92
eszcg07DK7yJ4/WllCIP7jDip0DORf4kpLLaoJbMV+w1YjRsOPnYMvD9u0QdQSHb
F6/bNQkZSUR9Kxm3azCCLHk9PXaXbsdpNs6IPIG8sYwcdA8yNFmaxnsdDZ3HKEGD
jxtFoBwzfGyRZ2NIadspGUuPDOLzM3HWRPixn6hcsOZnUJwRVWPscSC+SHafUnkI
/1WfduEgeIwnLqIGEP6zh0DGEXwi9cNq+uYy8Y5EMfVKoGiuRXLcKt6SmT0VYB6b
Gk4AdsTPeqQ7ndySLoK3Bndi3OPvorho1oTp9/ESueXX+5wbAoIBAQC3Fgc/8ojy
JKwErJA1x0OpaQI8ZkAgBs9dw76HS/gqcCTKaINDwlvXDKguj3sulaaWjRst8iOX
pAUva3Kf/Umzm2KHWbyGPbrH++E2DuVwdM8C3IGN+93V0ohzfAEmtcHwtD2l0013
IoDYRO94qfeKWylLD03OE7xCKKdPyFVGc+msiy3J1ASbGrIiKvmwDmxnscA89PeV
YUMae+2YCqy/1met1N71wJOzw0ZHICqaDnpd8Etk4PSB1pjwEcdrqyl9HI8AgNd1
lSQqSDgY1A0ZIrP03UPTxnepwAKKzRWZTVvnEYfPlImycGsjP6AWP3LaBuYbsOdY
p+QxyqcnaIKBAoIBADI+2/9hZ8y1uuNyW2k2KwraZX1h3VpcbpHsWvyUiyIrlyEP
+rWsidI9D57uiZtwn2QA9MLYLGUsq5Vk2vcdNdw4UjJord7qDC5r6MSc5glfciUj
osHXF6qEQEGbhI8BLg4GMtgDt1vB+celu2ksCpLdUuBb8quoNhrwPENQyYu7lbsS
LgWGYmNILtjvHU0EtbiR+j4Gvu2cAOYVXCMfEz5QGJQTOvTaMT+TPU7uIk6OZUBl
AwkEsbDYD1EOPWTCtEHNR+NcQt/XhGS5La2TKgtW0dMVX7PXUAZ7XLVJuilXX9rp
p7/0oXAKbXbNfj0GHtku+rIzyHUA4DHgys5JGv8CggEAa1TKoz538hx1i7fuQtiy
XdplqSr4ZM4ZOwrJ418x+Q8NQmvKqCqE1Kli3wjWWhT5OEE4sdLF8twA/i+rXweJ
8XUiad69mqUNnreW664H68lOoorKmIYTIort22XS9vKO46GGknQxcaoUhrTC/qYF
rGKM7qfmIO2I6/ARRcBX3ZmOX8yn5y4YFSWtUEKJZiDOhGu8GwAxNK10PU5xlzSK
2VvEJDArFT70V+oehQvibbYXHoMEb/tA2+0Gc5a4pfINvH7FhrIBnbj1HqR/3m5R
z258uQwN+1TaSfV6iAx6oQis2+V3DMYzgxxMcrmWC/TeS9rHg2xN87dZG6eGHqAy
AQKCAQEA+N7EZ6+P9ZIm1lhiYCJZKWHbSX+vWhke3jweptAAdWZuCfl4bgp+2pFl
YPIYNc2j5isGXpRz9/Dj+uhMUGW2CvrTpD77lIUbYvLxpCAXjV7m9obNMKG+C0QW
avEKhzRY+GzJTb0/HEj+fcnI5NTxVu4vpybNS3l6oHCLaOZpFfHLJVvqszIYhRsx
zlyXYQQaf0hDBNNODUbCwwsMgOfh4g6TpPh/HhSzhP/AygWuq18/HtTqwMF5yjtO
YCLavCp+hUuYnS95MYYrYUfCn78B6FrE6tJA1PC4ScwnTPLCEEJ9+zq/JnYw6Xhb
6PdueZl+bmh05Ii25Ou9Ac60Kgw19Q==
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFBDCCAuygAwIBAgIUfEdbWdFRD1TgQr9L/b6BG/TtrzQwDQYJKoZIhvcNAQEL
BQAwDTELMAkGA1UEAwwCQ0EwHhcNMjQwNDE5MDAyMDIwWhcNMjkwNDE4MDAyMDIw
WjAnMRQwEgYDVQQLDAtNU0cgU0VSVklDRTEPMA0GA1UEQQwGU0VSVkVSMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2fFMnYrXlQ8rPwOrMHFCRHbJe6fF
b+ZuVcXBakexI3a4d8unQJKeEqVX5POndEKNERUPXOcGrifV7ehxfmF/6oK2Xx4u
IrLHibV0XjAXY7YcTQj+ao18BgdVdrUi7cS8YYyyKoT+SP+GkEVYF5vJEgoTRy1h
dQQLZYp5AqsqoBbXr4rVaUdXDD8c1zWMwW6NGDIXWe0eAMMXyjqJRkdZ3FO4+53Y
4Zg2qUeF1GcDRamyC0dGykHeYmaly9M2tO6Mhwuh+wlMEbj55wxpPu3rlboMGIgi
+G2H3cHJLBn/1TkO5BZK3+2DhhUn0KuB3nfLsSP8v5H2A7FnnDuQaB64G4cRHprI
new7k02UnPXNefrX8JqlmSIIEzaMXSP4BNhKVMSSUmS5NHvkvxTZBlC7CBoB6W7y
10Ja807h0mHbMkV+FAVbfY8q2wAsUq3JPWizq6pZ+dgapDmZ0xCOZRnXqv2kBXas
UHwxWUL18T4VwlW97+aUr8afIkATZU11O6GXJbRbRjy8ofP7gcSIkeWOZUDrJlRM
K5PEkhVBOFuVVuty6uZLZleSBNkUOzsCeFxsdaJE9TKlVzxp6ewvtu4PTelKj31h
mTMCenTPcS9sa6gZTGIkdscOMy7lZjsMdlcyAxjUD59w1ruzDQyTn2tP9I6lLnKT
cCMmFKQfbyAZNcMCAwEAAaNCMEAwHQYDVR0OBBYEFEWIGqx7p7sYgYjtB/oUbChu
MdH3MB8GA1UdIwQYMBaAFMVE1jz77WweC8ao7bVYxujCdbDRMA0GCSqGSIb3DQEB
CwUAA4ICAQCIYQ5e0FbeZKwjdktLHw0cnGA3aVZhjbxJKU8rcDzeKDDH5SkwS25U
qIv4uvz+YY4DieSD0o3caTQhl4tx67Y9VcHmIQMjcMqFvzHBRAFZLidOgrqdJeIx
wD2c5kgrRf+8XTBQ9AG+D+XbI13dawlpAbJpu8fNdNO2XGzKu/qF+2f8u6E2Hx/U
LwJ1zqCXisr10CBIAwPrcsWBgM6oY9/YTaKRnLv4McZ9nil5yI5Y4odGTFs9zB8O
HrWlmCIQI47EevZdMJ+48xrGp2tkvAExGixcIS9reWkHVNomysg7pK+nE0jpTqAk
ZvcCXBKS1Bv+GWxrhKOA66SWTO9uTSr98D8hLKwpr3O76MGhtoqnxAwdX3KhdJe4
HUyFSb7uwizuNKNigknJwQtXB6lbqUEzoL5jSLEmHQ2v80felr6QDfrKD9sw590o
Gmwaa1riSqmnzZhE8ROumn+zknFjnovzde0RUIZ7o6zqM1hfSllNPPAMx2fzvXkI
KYjvBNgVsmZmklkEpVkAB0XijNDYGC/iwdG2os72jCxPAOMoBAnz1LFI4Rl044Ly
6MIdk7iPvGLLfkCFt/qb8/iSRKW1B6caqZ292vN34c+sLJOkrjDVRtKVdTAUyDNU
O01F9HUPOjVWmfZbCNfIz1gyMEeJtQ7eyZMC6Eg4DV2Gft4lHX4pNQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEbDCCAlQCAQAwJzEUMBIGA1UECwwLTVNHIFNFUlZJQ0UxDzANBgNVBEEMBlNF
UlZFUjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANnxTJ2K15UPKz8D
qzBxQkR2yXunxW/mblXFwWpHsSN2uHfLp0CSnhKlV+Tzp3RCjREVD1znBq4n1e3o
cX5hf+qCtl8eLiKyx4m1dF4wF2O2HE0I/mqNfAYHVXa1Iu3EvGGMsiqE/kj/hpBF
WBebyRIKE0ctYXUEC2WKeQKrKqAW16+K1WlHVww/HNc1jMFujRgyF1ntHgDDF8o6
iUZHWdxTuPud2OGYNqlHhdRnA0WpsgtHRspB3mJmpcvTNrTujIcLofsJTBG4+ecM
aT7t65W6DBiIIvhth93BySwZ/9U5DuQWSt/tg4YVJ9Crgd53y7Ej/L+R9gOxZ5w7
kGgeuBuHER6ayJ3sO5NNlJz1zXn61/CapZkiCBM2jF0j+ATYSlTEklJkuTR75L8U
2QZQuwgaAelu8tdCWvNO4dJh2zJFfhQFW32PKtsALFKtyT1os6uqWfnYGqQ5mdMQ
jmUZ16r9pAV2rFB8MVlC9fE+FcJVve/mlK/GnyJAE2VNdTuhlyW0W0Y8vKHz+4HE
iJHljmVA6yZUTCuTxJIVQThblVbrcurmS2ZXkgTZFDs7AnhcbHWiRPUypVc8aens
L7buD03pSo99YZkzAnp0z3EvbGuoGUxiJHbHDjMu5WY7DHZXMgMY1A+fcNa7sw0M
k59rT/SOpS5yk3AjJhSkH28gGTXDAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEA
jBlPoy8e+RHAB/mf49rHLELrcgG35tSdyPxxzMlbeN+zCwLIP00k0RKI+YvZS8mM
L8Ao1aUq8bCHrL2J1/wJh/yT9G/DYZqvfSkX+om+IGddQL/SKSdR/3oqaUuX7NMr
b9eR+HSUAMhUIIzuHiqGIgCwUtagdVU8BAJuEDoepEdS+2+sMCgDOAQNM0+qH+R0
33uWuZEokqwWaNc08h3mRtS1sLzcSQ9161iVzKJB44e6dWM/jqCZippNVWI0Skiu
UfP+uoYVuv1U9lEjX8cz54mL7iOs5snXJVpt8oO17zKozfLAyCFygU+gUNNnh/K/
T3EtvI7TlAAFMpYi5q95D4Mj3j6l2P0WcoLFrytCtRnLic6NCE5HYj2vScGN9WCh
GWcs4h+2MIY/VTxzn6AP82zXsJRusdfHoVAP/MDnP8YeIU9gtbWTJCl9DmdHQYp3
Xw6/TBCQwnQhbGquHVl4WFj8aO7Mm3jtVm5eLTRXNMCYPvqbOlaeeKZRsJkoyInf
gYj+LTZ2ke4moZ00tG4PwSvTj1CKuswa6HfB5l1UHmCuEhm4saS6MbgORj6UHh0W
L7gLtdUINzu/7KE3ZTI+d4kgpM2QFozjTa5SRYCBkZh/WhRMbI1lleWFw2dKFuyJ
IxJPaCw5XRVz8TM2jAEMqPSA9hhwhKl42ieQKMbBTqU=
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
f1Qiiw4+bNeBK2XZZKVXVltYUHrmUQ==
-----END PRIVATE KEY-----

Binary file not shown.

View file

@ -0,0 +1,9 @@
package main
import (
"PD1/internal/client"
)
func main(){
client.Run()
}

View file

@ -0,0 +1,9 @@
package main
import (
"PD1/internal/gateway"
)
func main(){
gateway.Run()
}

View file

@ -0,0 +1,9 @@
package main
import (
"PD1/internal/server"
)
func main(){
server.Run()
}

38
Projs/PD2/go.mod Normal file
View file

@ -0,0 +1,38 @@
module PD1
go 1.22.2
require (
github.com/gin-gonic/gin v1.10.0
github.com/mattn/go-sqlite3 v1.14.22
golang.org/x/crypto v0.23.0
software.sslmate.com/src/go-pkcs12 v0.4.0
)
require (
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

93
Projs/PD2/go.sum Normal file
View file

@ -0,0 +1,93 @@
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=

View file

@ -0,0 +1,323 @@
package client
import (
"PD1/internal/protocol"
"PD1/internal/utils/cryptoUtils"
"PD1/internal/utils/networking"
"crypto/x509"
"errors"
"flag"
"log"
"os"
"sort"
"strconv"
)
func Run() {
var userFile string
flag.StringVar(&userFile, "user", "userdata.p12", "Specify user data file")
flag.Parse()
if flag.NArg() == 0 {
log.Fatalln("No command provided. Use 'help' for instructions.")
}
//Get user KeyStore
password := readStdin("Insert keystore passphrase")
clientKeyStore, err := cryptoUtils.LoadKeyStore(userFile, password)
if err != nil {
log.Fatalln(err)
}
command := flag.Arg(0)
switch command {
case "send":
if flag.NArg() != 3 {
printError("MSG SERVICE: command error!")
showHelp()
os.Exit(1)
}
uid := flag.Arg(1)
plainSubject := flag.Arg(2)
plainBody := readStdin("Enter message content (limited to 1000 bytes):")
err := sendCommand(clientKeyStore, plainSubject, plainBody, uid)
if err != nil {
log.Fatalln(err)
}
case "askqueue":
if flag.NArg() > 3 {
printError("MSG SERVICE: command error!")
showHelp()
os.Exit(1)
}
pageInput := flag.Arg(1)
page := 1
if pageInput != "" {
if val, err := strconv.Atoi(pageInput); err == nil {
page = max(1, val)
}
}
pageSizeInput := flag.Arg(2)
pageSize := 5
if pageSizeInput != "" {
if val, err := strconv.Atoi(pageSizeInput); err == nil {
pageSize = max(1, val)
}
}
err := askQueueCommand(clientKeyStore, page, pageSize)
if err != nil {
log.Fatalln(err)
}
case "getmsg":
if flag.NArg() < 2 {
printError("MSG SERVICE: command error!")
showHelp()
os.Exit(1)
}
numString := flag.Arg(1)
num, err := strconv.Atoi(numString)
if err != nil {
log.Fatalln(err)
}
err = getMsgCommand(clientKeyStore, num)
if err != nil {
printError(err.Error())
}
case "help":
showHelp()
default:
printError("MSG SERVICE: command error!")
showHelp()
}
}
func sendCommand(clientKeyStore cryptoUtils.KeyStore, plainSubject, plainBody, uid string) error {
//Turn content to bytes
plainSubjectBytes, err := Marshal(plainSubject)
if err != nil {
return err
}
plainBodyBytes, err := Marshal(plainBody)
if err != nil {
return err
}
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
if err != nil {
return err
}
defer cl.Connection.Conn.Close()
receiverCert, err := getUserCert(cl, clientKeyStore, uid)
if err != nil {
return err
}
subject, err := clientKeyStore.EncryptMessageContent(receiverCert, plainSubjectBytes)
if err != nil {
return err
}
body, err := clientKeyStore.EncryptMessageContent(receiverCert, plainBodyBytes)
if err != nil {
return err
}
sendMsgPacket := protocol.NewSendMsgPacket(uid, subject, body)
if err := cl.Connection.Send(sendMsgPacket); err != nil {
return err
}
answerSendMsg, err := cl.Connection.Receive()
if err != nil {
return err
}
if answerSendMsg.Flag == protocol.FlagReportError {
reportError, err := protocol.UnmarshalReportError(answerSendMsg.Body)
if err != nil {
return err
}
return errors.New(reportError.ErrorMessage)
}
return nil
}
func getMsgCommand(clientKeyStore cryptoUtils.KeyStore, num int) error {
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
if err != nil {
return err
}
defer cl.Connection.Conn.Close()
packet := protocol.NewGetMsgPacket(num)
if err := cl.Connection.Send(packet); err != nil {
return err
}
receivedMsgPacket, err := cl.Connection.Receive()
if err != nil {
return err
}
if receivedMsgPacket.Flag == protocol.FlagReportError {
reportError, err := protocol.UnmarshalReportError(receivedMsgPacket.Body)
if err != nil {
return err
}
return errors.New(reportError.ErrorMessage)
}
answerGetMsg, err := protocol.UnmarshalAnswerGetMsg(receivedMsgPacket.Body)
if err != nil {
return err
}
senderCert, err := getUserCert(cl, clientKeyStore, answerGetMsg.FromUID)
if err != nil {
return err
}
decSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, answerGetMsg.Subject)
if err != nil {
return err
}
decBodyBytes, err := clientKeyStore.DecryptMessageContent(senderCert, answerGetMsg.Body)
if err != nil {
return err
}
subject, err := Unmarshal(decSubjectBytes)
if err != nil {
return err
}
body, err := Unmarshal(decBodyBytes)
if err != nil {
return err
}
message := newClientMessage(answerGetMsg.FromUID, answerGetMsg.ToUID, subject, body, answerGetMsg.Timestamp)
showMessage(message)
return nil
}
func getUserCert(cl networking.Client[protocol.Packet], keyStore cryptoUtils.KeyStore, uid string) (*x509.Certificate, error) {
getUserCertPacket := protocol.NewGetUserCertPacket(uid)
if err := cl.Connection.Send(getUserCertPacket); err != nil {
return nil, err
}
var answerGetUserCertPacket *protocol.Packet
answerGetUserCertPacket, err := cl.Connection.Receive()
if err != nil {
return nil, err
}
if answerGetUserCertPacket.Flag == protocol.FlagReportError {
reportError, err := protocol.UnmarshalReportError(answerGetUserCertPacket.Body)
if err != nil {
return nil, err
}
return nil, errors.New(reportError.ErrorMessage)
}
answerGetUserCert, err := protocol.UnmarshalAnswerGetUserCert(answerGetUserCertPacket.Body)
if err != nil {
return nil, err
}
userCert, err := x509.ParseCertificate(answerGetUserCert.Certificate)
if err != nil {
return nil, err
}
if err := keyStore.CheckCert(userCert, uid); err != nil {
return nil, err
}
return userCert, nil
}
func getManyMessagesInfo(cl networking.Client[protocol.Packet], keyStore cryptoUtils.KeyStore) (protocol.AnswerGetUnreadMsgsInfo, map[string]*x509.Certificate, error) {
answerGetUnreadMsgsInfoPacket, err := cl.Connection.Receive()
if err != nil {
return protocol.NewAnswerGetUnreadMsgsInfo(0, 0, nil), nil, err
}
if answerGetUnreadMsgsInfoPacket.Flag == protocol.FlagReportError {
reportError, err := protocol.UnmarshalReportError(answerGetUnreadMsgsInfoPacket.Body)
if err != nil {
return protocol.AnswerGetUnreadMsgsInfo{}, nil, err
}
return protocol.NewAnswerGetUnreadMsgsInfo(0, 0, nil), nil, errors.New(reportError.ErrorMessage)
}
answerGetUnreadMsgsInfo, err := protocol.UnmarshalAnswerGetUnreadMsgsInfo(answerGetUnreadMsgsInfoPacket.Body)
if err != nil {
return protocol.AnswerGetUnreadMsgsInfo{}, nil, err
}
//Create Set of needed certificates
senderSet := map[string]bool{}
for _, messageInfo := range answerGetUnreadMsgsInfo.MessagesInfo {
senderSet[messageInfo.FromUID] = true
}
certificatesMap := map[string]*x509.Certificate{}
//Get senders' certificates
for senderUID := range senderSet {
senderCert, err := getUserCert(cl, keyStore, senderUID)
if err == nil {
certificatesMap[senderUID] = senderCert
}
}
return answerGetUnreadMsgsInfo, certificatesMap, nil
}
func askQueueCommand(clientKeyStore cryptoUtils.KeyStore, page int, pageSize int) error {
cl, err := networking.NewClient[protocol.Packet](&clientKeyStore)
if err != nil {
return err
}
defer cl.Connection.Conn.Close()
return askQueueRec(cl, clientKeyStore, page, pageSize)
}
func askQueueRec(cl networking.Client[protocol.Packet], clientKeyStore cryptoUtils.KeyStore, page int, pageSize int) error {
requestUnreadMsgsQueuePacket := protocol.NewGetUnreadMsgsInfoPacket(page, pageSize)
if err := cl.Connection.Send(requestUnreadMsgsQueuePacket); err != nil {
return err
}
unreadMsgsInfo, certificates, err := getManyMessagesInfo(cl, clientKeyStore)
if err != nil {
return err
}
var clientMessages []ClientMessageInfo
for _, message := range unreadMsgsInfo.MessagesInfo {
var clientMessageInfo ClientMessageInfo
senderCert, ok := certificates[message.FromUID]
if !ok {
clientMessageInfo = newClientMessageInfo(message.Num,
message.FromUID,
"",
message.Timestamp,
errors.New("certificate needed to decrypt not received"))
clientMessages = append(clientMessages, clientMessageInfo)
continue
}
decryptedSubjectBytes, err := clientKeyStore.DecryptMessageContent(senderCert, message.Subject)
if err != nil {
clientMessageInfo = newClientMessageInfo(message.Num, message.FromUID, "", message.Timestamp, err)
clientMessages = append(clientMessages, clientMessageInfo)
continue
}
subject, err := Unmarshal(decryptedSubjectBytes)
if err != nil {
clientMessageInfo = newClientMessageInfo(message.Num, message.FromUID, "", message.Timestamp, err)
clientMessages = append(clientMessages, clientMessageInfo)
continue
}
clientMessageInfo = newClientMessageInfo(message.Num, message.FromUID, subject, message.Timestamp, nil)
clientMessages = append(clientMessages, clientMessageInfo)
}
//Sort the messages
sort.Slice(clientMessages, func(i, j int) bool {
return clientMessages[i].Num > clientMessages[j].Num
})
action := showMessagesInfo(unreadMsgsInfo.Page, unreadMsgsInfo.NumPages, clientMessages)
switch action {
case -1:
return askQueueRec(cl, clientKeyStore, max(1, unreadMsgsInfo.Page-1), pageSize)
case 1:
return askQueueRec(cl, clientKeyStore, max(1, unreadMsgsInfo.Page+1), pageSize)
default:
return nil
}
}

View file

@ -0,0 +1,47 @@
package client
import (
"encoding/json"
"time"
)
type ClientMessage struct {
FromUID string
ToUID string
Subject string
Body string
Timestamp time.Time
}
type ClientMessageInfo struct {
Num int
FromUID string
Timestamp time.Time
Subject string
decryptError error
}
func newClientMessage(fromUID string, toUID string, subject string, body string, timestamp time.Time) ClientMessage {
return ClientMessage{FromUID: fromUID, ToUID: toUID, Subject: subject, Body: body, Timestamp: timestamp}
}
func newClientMessageInfo(num int, fromUID string, subject string, timestamp time.Time, err error) ClientMessageInfo {
return ClientMessageInfo{Num: num, FromUID: fromUID, Subject: subject, Timestamp: timestamp, decryptError: err}
}
func Marshal(data any) ([]byte, error) {
subject, err := json.Marshal(data)
if err != nil {
return nil, err
}
return subject, nil
}
func Unmarshal(data []byte) (string, error) {
var c string
err := json.Unmarshal(data, &c)
if err != nil {
return "", err
}
return c, nil
}

View file

@ -0,0 +1,92 @@
package client
import (
"bufio"
"fmt"
"os"
"strings"
)
func readStdin(message string) string {
fmt.Println(message)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
return scanner.Text()
}
func printError(err string) {
fmt.Fprintln(os.Stderr, err)
}
func showHelp() {
fmt.Println("Comandos da aplicação cliente:")
fmt.Println("-user <FNAME>: Especifica o ficheiro com dados do utilizador. Por omissão, será assumido que esse ficheiro é userdata.p12.")
fmt.Println("send <UID> <SUBJECT>: Envia uma mensagem com assunto <SUBJECT> destinada ao utilizador com identificador <UID>. O conteúdo da mensagem será lido do stdin, e o tamanho deve ser limitado a 1000 bytes.")
fmt.Println("askqueue: Solicita ao servidor que lhe envie a lista de mensagens não lidas da queue do utilizador.")
fmt.Println("getmsg <NUM>: Solicita ao servidor o envio da mensagem da sua queue com número <NUM>.")
fmt.Println("help: Imprime instruções de uso do programa.")
}
func showMessagesInfo(page int, numPages int, messages []ClientMessageInfo) int {
if messages == nil {
fmt.Println("No unread messages in the queue")
return 0
}
for _, message := range messages {
if message.decryptError != nil {
fmt.Printf("ERROR: %v:%v:%v:", message.Num, message.FromUID, message.Timestamp)
fmt.Println(message.decryptError)
} else {
fmt.Printf("%v:%v:%v:%v\n", message.Num, message.FromUID, message.Timestamp, message.Subject)
}
}
fmt.Printf("Page %v/%v\n", page, numPages)
return messagesInfoPageNavigation(page, numPages)
}
func messagesInfoPageNavigation(page int, numPages int) int {
var action string
switch page {
case 1:
if page == numPages {
return 0
} else {
action = readStdin("Actions: quit/next")
}
case numPages:
action = readStdin("Actions: prev/quit")
default:
action = readStdin("prev/quit/next")
}
switch strings.ToLower(action) {
case "prev":
if page == 1 {
fmt.Println("Unavailable action: Already in first page")
messagesInfoPageNavigation(page, numPages)
} else {
return -1
}
case "quit":
return 0
case "next":
if page == numPages {
fmt.Println("Unavailable action: Already in last page")
messagesInfoPageNavigation(page, numPages)
} else {
return 1
}
default:
fmt.Println("Unknown action")
messagesInfoPageNavigation(page, numPages)
}
return 0
}
func showMessage(message ClientMessage) {
fmt.Printf("From: %s\n", message.FromUID)
fmt.Printf("To: %s\n", message.ToUID)
fmt.Printf("Subject: %s\n", message.Subject)
fmt.Printf("Body: %s\n", message.Body)
}

View file

@ -0,0 +1,5 @@
package gateway
func Run(){
}

View file

@ -0,0 +1,119 @@
package protocol
import (
"time"
)
type Body interface{}
type (
GetUserCert struct {
UID string `json:"uid"`
}
GetUnreadMsgsInfo struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
GetMsg struct {
Num int `json:"num"`
}
SendMsg struct {
ToUID string `json:"to_uid"`
Subject []byte `json:"subject"`
Body []byte `json:"body"`
}
AnswerGetUserCert struct {
UID string `json:"uid"`
Certificate []byte `json:"certificate"`
}
AnswerGetUnreadMsgsInfo struct {
Page int `json:"page"`
NumPages int `json:"num_pages"`
MessagesInfo []MsgInfo `json:"messages_info"`
}
MsgInfo struct {
Num int `json:"num"`
FromUID string `json:"from_uid"`
Subject []byte `json:"subject"`
Timestamp time.Time `json:"timestamp"`
}
AnswerGetMsg struct {
FromUID string `json:"from_uid"`
ToUID string `json:"to_uid"`
Subject []byte `json:"subject"`
Body []byte `json:"body"`
Timestamp time.Time `json:"timestamp"`
}
ReportError struct {
ErrorMessage string `json:"error"`
}
)
func NewGetUserCert(UID string) GetUserCert {
return GetUserCert{
UID: UID,
}
}
func NewGetUnreadMsgsInfo(page int, pageSize int) GetUnreadMsgsInfo {
return GetUnreadMsgsInfo{
Page: page,
PageSize: pageSize}
}
func NewGetMsg(num int) GetMsg {
return GetMsg{
Num: num,
}
}
func NewSendMsg(toUID string, subject []byte, body []byte) SendMsg {
return SendMsg{
ToUID: toUID,
Subject: subject,
Body: body,
}
}
func NewAnswerGetUserCert(uid string, certificate []byte) AnswerGetUserCert {
return AnswerGetUserCert{
UID: uid,
Certificate: certificate,
}
}
func NewAnswerGetUnreadMsgsInfo(page int, numPages int, messagesInfo []MsgInfo) AnswerGetUnreadMsgsInfo {
return AnswerGetUnreadMsgsInfo{Page: page, NumPages: numPages, MessagesInfo: messagesInfo}
}
func NewMsgInfo(num int, fromUID string, subject []byte, timestamp time.Time) MsgInfo {
return MsgInfo{
Num: num,
FromUID: fromUID,
Subject: subject,
Timestamp: timestamp,
}
}
func NewAnswerGetMsg(fromUID, toUID string, subject []byte, body []byte, timestamp time.Time, last bool) AnswerGetMsg {
return AnswerGetMsg{
FromUID: fromUID,
ToUID: toUID,
Subject: subject,
Body: body,
Timestamp: timestamp,
}
}
func NewReportError(errorMessage string) ReportError {
return ReportError{
ErrorMessage: errorMessage,
}
}

View file

@ -0,0 +1,245 @@
package server
import (
"PD1/internal/protocol"
"crypto/x509"
"database/sql"
"errors"
"fmt"
"log"
"time"
_ "github.com/mattn/go-sqlite3"
)
type DataStore struct {
db *sql.DB
}
func OpenDB() (DataStore, error) {
db, err := sql.Open("sqlite3", "server.db")
if err != nil {
return DataStore{}, err
}
ds := DataStore{db: db}
err = ds.CreateTables()
if err != nil {
return DataStore{}, err
}
return ds, nil
}
func (ds DataStore) CreateTables() error {
// Create users table
_, err := ds.db.Exec(`CREATE TABLE IF NOT EXISTS users (
UID TEXT PRIMARY KEY,
userCert BLOB
)`)
if err != nil {
return err
}
// Create messages table
_, err = ds.db.Exec(`CREATE TABLE IF NOT EXISTS messages (
fromUID TEXT,
toUID TEXT,
timestamp TIMESTAMP,
queue_position INT DEFAULT 0,
subject BLOB,
body BLOB,
status INT CHECK (status IN (0,1)),
PRIMARY KEY (toUID, fromUID, timestamp),
FOREIGN KEY(fromUID) REFERENCES users(UID),
FOREIGN KEY(toUID) REFERENCES users(UID)
)`)
if err != nil {
return err
}
// Define a trigger to automatically assign numbers for each message of each user starting from 1
_, err = ds.db.Exec(`
CREATE TRIGGER IF NOT EXISTS assign_queue_position
AFTER INSERT ON messages
FOR EACH ROW
BEGIN
UPDATE messages
SET queue_position = (
SELECT COUNT(*)
FROM messages
WHERE toUID = NEW.toUID
)
WHERE toUID = NEW.toUID AND rowid = NEW.rowid;
END;
`)
if err != nil {
return err
}
return nil
}
func (ds DataStore) GetMessage(toUID string, position int) (*protocol.AnswerGetMsg, error) {
var serverMessage protocol.AnswerGetMsg
query := `
SELECT fromUID, toUID, subject, body, timestamp
FROM messages
WHERE toUID = ? AND queue_position = ?
`
// Execute the query
row := ds.db.QueryRow(query, toUID, position)
err := row.Scan(&serverMessage.FromUID, &serverMessage.ToUID, &serverMessage.Subject, &serverMessage.Body, &serverMessage.Timestamp)
if err == sql.ErrNoRows {
log.Printf("No message with NUM %v for UID %v\n", position, toUID)
errorMessage := fmt.Sprintln("MSG SERVICE: unknown message!")
error := errors.New(errorMessage)
return nil, error
}
answer := protocol.NewAnswerGetMsg(serverMessage.FromUID, serverMessage.ToUID, serverMessage.Subject, serverMessage.Body, serverMessage.Timestamp, true)
return &answer, nil
}
func (ds DataStore) MarkMessageInQueueAsRead(toUID string, position int) {
query := `
UPDATE messages
SET status = 1
WHERE (fromUID,toUID,timestamp) = (
SELECT fromUID,toUID,timestamp
FROM messages
WHERE toUID = ? AND queue_position = ?
)
`
// Execute the SQL statement
_, err := ds.db.Exec(query, toUID, position)
if err != nil {
log.Printf("Error marking the message in position %v from UID %v as read: %v", position, toUID, err)
}
}
func (ds DataStore) GetUnreadMsgsInfo(toUID string, page int, pageSize int) (protocol.AnswerGetUnreadMsgsInfo, error) {
// Retrieve the total count of unread messages
var totalCount int
err := ds.db.QueryRow("SELECT COUNT(*) FROM messages WHERE toUID = ? AND status = 0", toUID).Scan(&totalCount)
if err == sql.ErrNoRows {
return protocol.NewAnswerGetUnreadMsgsInfo(0, 0, []protocol.MsgInfo{}), nil
}
// Query to retrieve all messages from the user's queue
query := `
SELECT
fromUID,
toUID,
timestamp,
queue_position,
subject,
status
FROM messages
WHERE
toUID = ? AND status = 0
ORDER BY
queue_position DESC
LIMIT ? OFFSET ?;
`
// Execute the query
rows, err := ds.db.Query(query, toUID, pageSize, (page-1)*pageSize)
if err != nil {
log.Printf("Error getting unread messages for UID %v: %v", toUID, err)
}
defer rows.Close()
messageInfoPackets := []protocol.MsgInfo{}
for rows.Next() {
var fromUID string
var subject []byte
var timestamp time.Time
var queuePosition, status int
if err := rows.Scan(&fromUID, &toUID, &timestamp, &queuePosition, &subject, &status); err != nil {
return protocol.AnswerGetUnreadMsgsInfo{}, err
}
answerGetUnreadMsgsInfo := protocol.NewMsgInfo(queuePosition, fromUID, subject, timestamp)
messageInfoPackets = append(messageInfoPackets, answerGetUnreadMsgsInfo)
}
if err := rows.Err(); err != nil {
log.Printf("Error when getting messages for UID %v: %v", toUID, err)
return protocol.AnswerGetUnreadMsgsInfo{}, err
}
numberOfPages := (totalCount + pageSize - 1) / pageSize
currentPage := min(numberOfPages, page)
return protocol.NewAnswerGetUnreadMsgsInfo(currentPage, numberOfPages, messageInfoPackets), nil
}
func (ds DataStore) AddMessageToQueue(fromUID string, message protocol.SendMsg) error {
query := `
INSERT INTO messages (fromUID, toUID, subject, body, timestamp, status)
VALUES (?, ?, ?, ?, ?, 0)
`
// Execute the SQL statement
currentTime := time.Now()
_, err := ds.db.Exec(query, fromUID, message.ToUID, message.Subject, message.Body, currentTime)
if err != nil {
log.Printf("Error adding message to UID %v: %v", fromUID, err)
return err
}
return nil
}
func (ds DataStore) GetUserCertificate(uid string) (protocol.AnswerGetUserCert,error) {
query := `
SELECT userCert
FROM users
WHERE UID = ?
`
// Execute the SQL query
var userCertBytes []byte
err := ds.db.QueryRow(query, uid).Scan(&userCertBytes)
if err == sql.ErrNoRows {
errorMessage := fmt.Sprintf("No certificate for UID %v found in the database", uid)
log.Println(errorMessage)
return protocol.AnswerGetUserCert{},errors.New(errorMessage)
}
return protocol.NewAnswerGetUserCert(uid, userCertBytes),nil
}
func (ds DataStore) userExists(uid string) bool {
// Prepare the SQL statement for checking if a user exists
query := `
SELECT COUNT(*)
FROM users
WHERE UID = ?
`
var count int
// Execute the SQL query
err := ds.db.QueryRow(query, uid).Scan(&count)
if err != nil || count == 0 {
log.Printf("user with UID %v does not exist\n", uid)
return false
}
return true
}
func (ds DataStore) storeUserCertIfNotExists(uid string, cert x509.Certificate) error {
// Check if the user already exists
if ds.userExists(uid) {
return nil
}
// Insert the user certificate
insertQuery := `
INSERT INTO users (UID, userCert)
VALUES (?, ?)
`
_, err := ds.db.Exec(insertQuery, uid, cert.Raw)
if err != nil {
return fmt.Errorf("error storing user certificate for UID %s: %v", uid, err)
}
log.Printf("User certificate for UID %s stored successfully.\n", uid)
return nil
}

View file

@ -0,0 +1,14 @@
package server
import (
"bufio"
"fmt"
"os"
)
func readStdin(message string) string {
fmt.Println(message)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
return scanner.Text()
}

View file

@ -0,0 +1,151 @@
package server
import (
"PD1/internal/protocol"
"PD1/internal/utils/cryptoUtils"
"log"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
//func clientHandler(connection networking.Connection[protocol.Packet], dataStore DataStore) {
// defer connection.Conn.Close()
//
// //Get certificate sent by user
// clientCert := connection.GetPeerCertificate()
// //Get the OID values
// oidMap := cryptoUtils.ExtractAllOIDValues(clientCert)
// //Check if certificate usage is MSG SERVICE
// usage := oidMap["2.5.4.11"]
// if usage == "" {
// log.Fatalln("User certificate does not have the correct usage")
// }
// //Get the UID of this user
// UID := oidMap["2.5.4.65"]
// if UID == "" {
// log.Fatalln("User certificate does not specify it's PSEUDONYM")
// }
// err := dataStore.storeUserCertIfNotExists(UID, *clientCert)
// if err != nil {
// log.Fatalln(err)
// }
//}
func HandleGetUserCert(c *gin.Context, dataStore DataStore) {
user := c.Param("user")
userCertPacket, err := dataStore.GetUserCertificate(user)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, userCertPacket)
}
}
func HandleGetUnreadMsgsInfo(c *gin.Context, dataStore DataStore) {
user := c.Param("user")
var getUnreadMsgsInfo protocol.GetUnreadMsgsInfo
if err := c.BindJSON(getUnreadMsgsInfo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if getUnreadMsgsInfo.Page <= 0 || getUnreadMsgsInfo.PageSize <= 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Page and PageSize need to be >= 1"})
return
}
unreadMsgsInfo, err := dataStore.GetUnreadMsgsInfo(user, getUnreadMsgsInfo.Page, getUnreadMsgsInfo.PageSize)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, unreadMsgsInfo)
}
func HandleSendMessage(c *gin.Context, dataStore DataStore) {
sender := c.Param("user")
var message protocol.SendMsg
if err := c.BindJSON(message); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if message.ToUID == sender {
c.JSON(http.StatusBadRequest, gin.H{"error": "Message sender and receiver cannot be the same user"})
return
}
if !dataStore.userExists(message.ToUID) {
c.JSON(http.StatusBadRequest, gin.H{"error": "Message receiver does not exist"})
return
}
err := dataStore.AddMessageToQueue(sender, message)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, nil)
}
func HandleGetMessage(c *gin.Context, dataStore DataStore) {
user := c.Param("user")
numStr := c.Param("num")
num, err := strconv.Atoi(numStr)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
message, reportError := dataStore.GetMessage(user, num)
if reportError != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
}
dataStore.MarkMessageInQueueAsRead(user, num)
c.JSON(http.StatusOK, message)
}
func Run() {
//Open connection to DB
dataStore, err := OpenDB()
if err != nil {
log.Fatalln(err)
}
defer dataStore.db.Close()
//Read server keystore
keystorePassphrase := readStdin("Insert keystore passphrase")
serverKeyStore, err := cryptoUtils.LoadKeyStore("certs/server/server.p12", keystorePassphrase)
if err != nil {
log.Fatalln(err)
}
r := gin.Default()
r.GET("/message/:user/:num", func(c *gin.Context) {
HandleGetMessage(c, dataStore)
})
r.GET("/queue/:user", func(c *gin.Context) {
HandleGetUnreadMsgsInfo(c, dataStore)
})
r.GET("/cert/:user", func(c *gin.Context) {
HandleGetUserCert(c, dataStore)
})
r.POST("/message/:user", func(c *gin.Context) {
HandleSendMessage(c, dataStore)
})
server := http.Server{
Addr: "0.0.0.0:8080",
Handler: r,
TLSConfig: serverKeyStore.GetTLSConfig(),
}
err = server.ListenAndServeTLS("", "")
if err!=nil {
log.Fatal(err.Error())
}
}

View file

@ -0,0 +1,283 @@
package cryptoUtils
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/binary"
"errors"
"time"
"log"
"os"
"golang.org/x/crypto/chacha20poly1305"
"software.sslmate.com/src/go-pkcs12"
)
type KeyStore struct {
cert *x509.Certificate
caCertChain []*x509.Certificate
privKey *rsa.PrivateKey
}
func (k KeyStore) GetCert() *x509.Certificate {
return k.cert
}
func (k KeyStore) GetCACertChain() []*x509.Certificate {
return k.caCertChain
}
func (k KeyStore) GetPrivKey() *rsa.PrivateKey {
return k.privKey
}
func ExtractAllOIDValues(cert *x509.Certificate) map[string]string {
oidValueMap := make(map[string]string)
for _, name := range cert.Subject.Names {
oid := name.Type.String()
value := name.Value.(string)
oidValueMap[oid] = value
}
return oidValueMap
}
func LoadKeyStore(keyStorePath string, password string) (KeyStore, error) {
var privKey *rsa.PrivateKey
keystoreBytes, err := os.ReadFile(keyStorePath)
if err != nil {
return KeyStore{}, err
}
privKeyInterface, cert, caCerts, err := pkcs12.DecodeChain(keystoreBytes, password)
if err != nil {
return KeyStore{}, err
}
privKey, ok := privKeyInterface.(*rsa.PrivateKey)
if !ok {
return KeyStore{}, err
}
if err := privKey.Validate(); err != nil {
return KeyStore{}, err
}
return KeyStore{cert: cert, caCertChain: caCerts, privKey: privKey}, err
}
// Check if the cert is signed by the CA and is for the correct user
func (k KeyStore) CheckCert(cert *x509.Certificate, uid string) error {
caCertPool := x509.NewCertPool()
for _, caCert := range k.caCertChain {
caCertPool.AddCert(caCert)
}
opts := x509.VerifyOptions{
Roots: caCertPool,
}
// Check if the certificate is signed by the specified CA
_, err := cert.Verify(opts)
if err != nil {
log.Println("Certificate not signed by a trusted CA")
return err
}
if cert.NotAfter.Before(time.Now()) {
return errors.New("certificate has expired")
}
if cert.NotBefore.After(time.Now()) {
return errors.New("certificate is not valid yet")
}
//Check if the pseudonym field is set to UID
oidMap := ExtractAllOIDValues(cert)
if oidMap["2.5.4.65"] != uid {
log.Println("Certificate does not belong to the message's receiver")
return err
}
return nil
}
func (k *KeyStore) GetTLSConfig() *tls.Config {
certificate := tls.Certificate{Certificate: [][]byte{k.cert.Raw}, PrivateKey: k.privKey, Leaf: k.cert}
//Add the CA certificate chain to a CertPool
caCertPool := x509.NewCertPool()
for _, caCert := range k.caCertChain {
caCertPool.AddCert(caCert)
}
config := &tls.Config{
Certificates: []tls.Certificate{certificate},
}
return config
}
func (k *KeyStore) GetServerTLSConfig() *tls.Config {
tlsConfig := k.GetTLSConfig()
//Add the CA certificate chain to a CertPool
caCertPool := x509.NewCertPool()
for _, caCert := range k.caCertChain {
caCertPool.AddCert(caCert)
}
tlsConfig.ClientCAs = caCertPool
tlsConfig.ClientAuth = tls.RequireAnyClientCert
tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
// Verify the peer's certificate
opts := x509.VerifyOptions{
Roots: caCertPool,
}
for _, certBytes := range rawCerts {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return err
}
if cert.NotAfter.Before(time.Now()) {
return errors.New("certificate has expired")
}
if cert.NotBefore.After(time.Now()) {
return errors.New("certificate is not valid yet")
}
// Check if the certificate is signed by the specified CA
_, err = cert.Verify(opts)
if err != nil {
return errors.New("certificate not signed by trusted CA")
}
}
return nil
}
return tlsConfig
}
func (k *KeyStore) GetClientTLSConfig() *tls.Config {
tlsConfig := k.GetTLSConfig()
//Add the CA certificate chain to a CertPool
caCertPool := x509.NewCertPool()
for _, caCert := range k.caCertChain {
caCertPool.AddCert(caCert)
}
tlsConfig.RootCAs = caCertPool
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
// Verify the peer's certificate
opts := x509.VerifyOptions{
Roots: caCertPool,
}
for _, certBytes := range rawCerts {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return err
}
if cert.NotAfter.Before(time.Now()) {
return errors.New("certificate has expired")
}
if cert.NotBefore.After(time.Now()) {
return errors.New("certificate is not valid yet")
}
oidMap := ExtractAllOIDValues(cert)
// Check if the certificate is signed by the specified CA
_, err = cert.Verify(opts)
if err != nil {
return errors.New("certificate not signed by trusted CA")
}
//Check if the pseudonym field is set to "SERVER"
if oidMap["2.5.4.65"] != "SERVER" {
return errors.New("peer isn't the server")
}
}
return nil
}
return tlsConfig
}
func (k KeyStore) EncryptMessageContent(receiverCert *x509.Certificate, content []byte) ([]byte, error) {
// Digital envolope
// Create a random symmetric key
dataKey := make([]byte, 32)
if _, err := rand.Read(dataKey); err != nil {
return nil, err
}
cipher, err := chacha20poly1305.New(dataKey)
if err != nil {
return nil, err
}
nonce := make([]byte, cipher.NonceSize(), cipher.NonceSize()+len(content)+cipher.Overhead())
if _, err = rand.Read(nonce); err != nil {
return nil, err
}
// sign the message and append the signature
hashedContent := sha256.Sum256(content)
signature, err := rsa.SignPKCS1v15(nil, k.privKey, crypto.SHA256, hashedContent[:])
if err != nil {
return nil, err
}
content = pair(signature, content)
ciphertext := cipher.Seal(nonce, nonce, content, nil)
receiverPubKey := receiverCert.PublicKey.(*rsa.PublicKey)
encryptedDataKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, receiverPubKey, dataKey, nil)
if err != nil {
return nil, err
}
return pair(encryptedDataKey, ciphertext), nil
}
func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) ([]byte, error) {
encryptedDataKey, encryptedMsg := unPair(cipherContent)
dataKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, k.GetPrivKey(), encryptedDataKey, nil)
if err != nil {
return nil, err
}
// decrypt ciphertext
cipher, err := chacha20poly1305.New(dataKey)
if err != nil {
return nil, err
}
nonce, ciphertext := encryptedMsg[:cipher.NonceSize()], encryptedMsg[cipher.NonceSize():]
contentAndSig, err := cipher.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, err
}
// check signature with sender public key
signature, content := unPair(contentAndSig)
hashedContent := sha256.Sum256(content)
senderKey := senderCert.PublicKey.(*rsa.PublicKey)
if err := rsa.VerifyPKCS1v15(senderKey, crypto.SHA256, hashedContent[:], signature); err != nil {
return nil, err
}
return content, nil
}
func pair(l []byte, r []byte) []byte {
length := len(l)
lenBytes := make([]byte, 2)
binary.BigEndian.PutUint16(lenBytes, uint16(length))
lWithLen := append(lenBytes, l...)
return append(lWithLen, r...)
}
func unPair(pair []byte) ([]byte, []byte) {
lenBytes := pair[:2]
pair = pair[2:]
length := binary.BigEndian.Uint16(lenBytes)
l := pair[:length]
r := pair[length:]
return l, r
}

View file

@ -0,0 +1,23 @@
package networking
import (
"crypto/tls"
)
type ClientTLSConfigProvider interface {
GetClientTLSConfig() *tls.Config
}
type Client[T any] struct {
Connection Connection[T]
}
func NewClient[T any](clientTLSConfigProvider ClientTLSConfigProvider) (Client[T],error) {
dialConn, err := tls.Dial("tcp", "localhost:8080", clientTLSConfigProvider.GetClientTLSConfig())
if err != nil {
return Client[T]{},err
}
conn := NewConnection[T](dialConn)
return Client[T]{Connection: conn},nil
}

View file

@ -0,0 +1,51 @@
package networking
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"io"
"log"
)
type Connection[T any] struct {
Conn *tls.Conn
encoder *json.Encoder
decoder *json.Decoder
}
func NewConnection[T any](netConn *tls.Conn) Connection[T] {
return Connection[T]{
Conn: netConn,
encoder: json.NewEncoder(netConn),
decoder: json.NewDecoder(netConn),
}
}
func (c Connection[T]) Send(obj T) error {
if err := c.encoder.Encode(&obj); err!=nil {
if err == io.EOF {
log.Println("Connection closed by peer")
}
return err
}
//Return true as connection active
return nil
}
func (c Connection[T]) Receive() (*T, error) {
var obj T
if err := c.decoder.Decode(&obj); err != nil {
if err == io.EOF {
log.Println("Connection closed by peer")
}
return nil,err
}
//Return true as connection active
return &obj, nil
}
func (c Connection[T]) GetPeerCertificate() *x509.Certificate {
state := c.Conn.ConnectionState()
return state.PeerCertificates[0]
}

View file

@ -0,0 +1,56 @@
package networking
import (
"crypto/tls"
"log"
"net"
)
type ServerTLSConfigProvider interface {
GetServerTLSConfig() *tls.Config
}
type Server[T any] struct {
listener net.Listener
C chan Connection[T]
}
func NewServer[T any](serverTLSConfigProvider ServerTLSConfigProvider) (Server[T], error) {
listener, err := tls.Listen("tcp", "127.0.0.1:8080", serverTLSConfigProvider.GetServerTLSConfig())
if err != nil {
return Server[T]{}, err
}
return Server[T]{
listener: listener,
C: make(chan Connection[T]),
}, nil
}
func (s *Server[T]) ListenLoop() {
for {
listenerConn, err := s.listener.Accept()
if err != nil {
log.Println("Server could not accept connection")
continue
}
tlsConn, ok := listenerConn.(*tls.Conn)
if !ok {
log.Println("Connection is not a TLS connection")
continue
}
if err := tlsConn.Handshake(); err != nil {
log.Println(err)
continue
}
state := tlsConn.ConnectionState()
if len(state.PeerCertificates) == 0 {
log.Println("Client did not provide a certificate")
continue
}
conn := NewConnection[T](tlsConn)
s.C <- conn
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
Projs/PD2/server.db Normal file

Binary file not shown.

23
Projs/PD2/tokefile.toml Normal file
View file

@ -0,0 +1,23 @@
[targets.setup]
wildcards=[["golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest"]]
cmd="go install @@"
[targets.check]
wildcards=[["go vet ./...","shadow ./..."]]
cmd="@@"
[targets.build]
cmd="go build"
[targets.server]
cmd="go run ./cmd/server/server.go"
[targets.send]
cmd="go run ./cmd/client/client.go -user certs/client1/client1.p12 send CL2 testsubject"
[targets.askQueue]
cmd="go run ./cmd/client/client.go -user certs/client2/client2.p12 askqueue"
[targets.fakeAskQueue]
cmd="go run ./cmd/client/client.go -user certs/FakeClient1/client1.p12 askqueue"

0
TPs/TP02/py/cfich_aes_cbc.py Executable file → Normal file
View file

0
TPs/TP02/py/cfich_chacha20.py Executable file → Normal file
View file

0
TPs/TP02/py/chacha20_int_attck.py Executable file → Normal file
View file

View file

@ -1 +0,0 @@
US9ÃhMé„(#c…™b¸ÎÙoe@]<5D>.Jµ?K.Óké<6B>|Da¡vz>Z:’‚¯"]

0
TPs/TP03/pbenc_aes_ctr_hmac Executable file → Normal file
View file

Binary file not shown.