зеркало из https://github.com/microsoft/ivy.git
168 строки
5.1 KiB
C++
168 строки
5.1 KiB
C++
#include "errno.h"
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
#include "gnutls/gnutls.h"
|
|
#include <vector>
|
|
|
|
std::vector<char> client_input;
|
|
std::vector<char> server_input;
|
|
|
|
|
|
ssize_t client_push_func(gnutls_transport_ptr_t ptr, const void* data, size_t len) {
|
|
char *d = (char *)data;
|
|
for (size_t i = 0; i < len; i++) {
|
|
server_input.push_back(d[i]);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
ssize_t client_pull_func(gnutls_transport_ptr_t ptr, void* data, size_t len){
|
|
size_t res;
|
|
res = client_input.size();
|
|
if (len < res)
|
|
res = len;
|
|
if (res == 0) {
|
|
errno = EAGAIN;
|
|
return -1;
|
|
}
|
|
char *d = (char *)data;
|
|
for (size_t i = 0; i < res; i++) {
|
|
d[i] = client_input[i];
|
|
}
|
|
client_input.erase(client_input.begin(),client_input.begin()+res);
|
|
return res;
|
|
}
|
|
|
|
ssize_t server_push_func(gnutls_transport_ptr_t ptr, const void* data, size_t len) {
|
|
char *d = (char *)data;
|
|
for (size_t i = 0; i < len; i++) {
|
|
client_input.push_back(d[i]);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
ssize_t server_pull_func(gnutls_transport_ptr_t ptr, void* data, size_t len){
|
|
size_t res;
|
|
res = server_input.size();
|
|
if (len < res)
|
|
res = len;
|
|
if (res == 0) {
|
|
errno = EAGAIN;
|
|
return -1;
|
|
}
|
|
char *d = (char *)data;
|
|
for (size_t i = 0; i < res; i++) {
|
|
d[i] = server_input[i];
|
|
}
|
|
server_input.erase(server_input.begin(),server_input.begin()+res);
|
|
return res;
|
|
}
|
|
|
|
int main () {
|
|
gnutls_session_t client;
|
|
if (gnutls_init (& client, GNUTLS_CLIENT | GNUTLS_NONBLOCK) != GNUTLS_E_SUCCESS) {
|
|
std::cout << "gnutls_init failed\n";
|
|
exit(1);
|
|
}
|
|
gnutls_transport_ptr_t ptr;
|
|
gnutls_transport_set_ptr (client, ptr);
|
|
gnutls_transport_set_push_function (client, client_push_func);
|
|
gnutls_transport_set_pull_function (client, client_pull_func);
|
|
const char *errpos;
|
|
int pres = gnutls_priority_set_direct (client,"NORMAL:+ANON-ECDH:+ANON-DH",&errpos);
|
|
if (pres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "set_default_priority returned error\n";
|
|
exit(1);
|
|
}
|
|
gnutls_anon_client_credentials_t cred;
|
|
int crres = gnutls_anon_allocate_client_credentials (&cred);
|
|
if (crres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "anon_allocate_client_credentials returned error\n";
|
|
exit(1);
|
|
}
|
|
int cres = gnutls_credentials_set (client, GNUTLS_CRD_ANON, &cred);
|
|
if (cres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "gnutls_credentials_set returned error\n";
|
|
exit(1);
|
|
}
|
|
int res = gnutls_handshake (client);
|
|
if (res != GNUTLS_E_SUCCESS) {
|
|
if (res == GNUTLS_E_AGAIN) {
|
|
std::cerr << "gnutls_handshake returned EAGAIN\n";
|
|
} else {
|
|
std::cerr << "gnutls_handshake returned error\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
gnutls_session_t server;
|
|
if (gnutls_init (& server, GNUTLS_SERVER | GNUTLS_NONBLOCK) != GNUTLS_E_SUCCESS) {
|
|
std::cout << "gnutls_init failed\n";
|
|
exit(1);
|
|
}
|
|
gnutls_transport_set_ptr (server, ptr);
|
|
gnutls_transport_set_push_function (server, server_push_func);
|
|
gnutls_transport_set_pull_function (server, server_pull_func);
|
|
pres = gnutls_priority_set_direct (server,"NORMAL:+ANON-ECDH:+ANON-DH",&errpos);
|
|
if (pres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "set_default_priority returned error\n";
|
|
exit(1);
|
|
}
|
|
gnutls_anon_server_credentials_t scred;
|
|
crres = gnutls_anon_allocate_server_credentials (&scred);
|
|
if (crres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "anon_allocate_server_credentials returned error\n";
|
|
exit(1);
|
|
}
|
|
cres = gnutls_credentials_set (server, GNUTLS_CRD_ANON, &scred);
|
|
if (cres != GNUTLS_E_SUCCESS) {
|
|
std::cerr << "gnutls_credentials_set returned error\n";
|
|
exit(1);
|
|
}
|
|
res = gnutls_handshake (server);
|
|
if (res != GNUTLS_E_SUCCESS) {
|
|
if (res == GNUTLS_E_AGAIN) {
|
|
std::cerr << "gnutls_handshake returned EAGAIN\n";
|
|
} else {
|
|
std::cerr << "gnutls_handshake returned error\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
res = gnutls_handshake (client);
|
|
if (res != GNUTLS_E_SUCCESS) {
|
|
if (res == GNUTLS_E_AGAIN) {
|
|
std::cerr << "gnutls_handshake returned EAGAIN\n";
|
|
} else {
|
|
std::cerr << "gnutls_handshake returned error\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
res = gnutls_handshake (server);
|
|
if (res != GNUTLS_E_SUCCESS) {
|
|
if (res == GNUTLS_E_AGAIN) {
|
|
std::cerr << "gnutls_handshake(server) returned EAGAIN\n";
|
|
} else {
|
|
std::cerr << "gnutls_handshake(server) returned error\n";
|
|
exit(1);
|
|
}
|
|
} else {
|
|
std::cerr << "gnutls_handshake(server) returned SUCCESS\n";
|
|
}
|
|
|
|
res = gnutls_handshake (client);
|
|
if (res != GNUTLS_E_SUCCESS) {
|
|
if (res == GNUTLS_E_AGAIN) {
|
|
std::cerr << "gnutls_handshake(client) returned EAGAIN\n";
|
|
} else {
|
|
std::cerr << "gnutls_handshake(client) returned error\n";
|
|
exit(1);
|
|
}
|
|
} else {
|
|
std::cerr << "gnutls_handshake(client) returned SUCCESS\n";
|
|
}
|
|
|
|
return 0;
|
|
}
|