コード例 #1
0
ファイル: tlssimpleserver.c プロジェクト: eduardsui/tlse
int main(int argc , char *argv[]) {
    int socket_desc , client_sock , read_size;
    socklen_t c;
    struct sockaddr_in server , client;
    char client_message[0xFFFF];
    const char msg[] = "HTTP/1.1 200 OK\r\nContent-length: 31\r\nContent-type: text/plain\r\n\r\nHello world from TLSe (TLS 1.2)";

#ifdef _WIN32
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#else
    signal(SIGPIPE, SIG_IGN);
#endif

    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1) {
        printf("Could not create socket");
        return 0;
    }
     
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(2000);
     
    int enable = 1;
    setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));

    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) {
        perror("bind failed. Error");
        return 1;
    }
     
    listen(socket_desc , 3);
     
    c = sizeof(struct sockaddr_in);

    unsigned int size;

    SSL *server_ctx = SSL_CTX_new(SSLv3_server_method());
    if (!server_ctx) {
        fprintf(stderr, "Error creating server context\n");
        return -1;
    }
    SSL_CTX_use_certificate_file(server_ctx, "testcert/fullchain.pem", SSL_SERVER_RSA_CERT);
    SSL_CTX_use_PrivateKey_file(server_ctx, "testcert/privkey.pem", SSL_SERVER_RSA_KEY);

    if (!SSL_CTX_check_private_key(server_ctx)) {
        fprintf(stderr, "Private key not loaded\n");
        return -2;
    }

    while (1) {
        client_sock = accept(socket_desc, (struct sockaddr *)&client, &c);
        if (client_sock < 0) {
            fprintf(stderr, "Accept failed\n");
            return -3;
        }
        SSL *client = SSL_new(server_ctx);
        if (!client) {
            fprintf(stderr, "Error creating SSL client\n");
            return -4;
        }
        SSL_set_fd(client, client_sock);
        if (SSL_accept(client)) {
            fprintf(stderr, "Cipher %s\n", tls_cipher_name(client));
            while ((read_size = SSL_read(client, client_message, sizeof(client_message))) >= 0) {
                fwrite(client_message, read_size, 1, stdout);
                
                if (SSL_write(client, msg, strlen(msg)) < 0)
                    fprintf(stderr, "Error in SSL write\n");
                break;
            }
        } else
            fprintf(stderr, "Error in handshake\n");
        
        SSL_shutdown(client);
#ifdef __WIN32
        shutdown(client_sock, SD_BOTH);
        closesocket(client_sock);
#else
        shutdown(client_sock, SHUT_RDWR);
        close(client_sock);
#endif
        SSL_free(client);
    }
    SSL_CTX_free(server_ctx);
    return 0;
}
コード例 #2
0
ファイル: tlshelloworld.c プロジェクト: EmuxEvans/tlse
int main(int argc , char *argv[]) {
    int socket_desc , client_sock , read_size;
    socklen_t c;
    struct sockaddr_in server , client;
    char client_message[0xFFFF];

#ifdef _WIN32
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#else
    signal(SIGPIPE, SIG_IGN);
#endif

    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1) {
        printf("Could not create socket");
        return 0;
    }

    int port = 2000;
    if (argc > 1) {
        port = atoi(argv[1]);
        if (port <= 0)
            port = 2000;
    }
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(port);
     
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) {
        perror("bind failed. Error");
        return 1;
    }
    int enable = 1;
    setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
     
    listen(socket_desc , 3);
     
    c = sizeof(struct sockaddr_in);

    unsigned int size;

    struct TLSContext *server_context = tls_create_context(1, TLS_V12);
    // load keys
    load_keys(server_context, "testcert/fullchain.pem", "testcert/privkey.pem");
    
    char source_buf[0xFFFF];
    int source_size = read_from_file("tlshelloworld.c", source_buf, 0xFFFF);
    while (1) {
        identity_str[0] = 0;

        client_sock = accept(socket_desc, (struct sockaddr *)&client, &c);
        if (client_sock < 0) {
            perror("accept failed");
            return 1;
        }
        struct TLSContext *context = tls_accept(server_context);

        // uncomment next line to request client certificate
        tls_request_client_certificate(context);

        // make the TLS context serializable (this must be called before negotiation)
        tls_make_exportable(context, 1);

        fprintf(stderr, "Client connected\n");
        while ((read_size = recv(client_sock, client_message, sizeof(client_message), 0)) > 0) {
            if (tls_consume_stream(context, client_message, read_size, verify_signature) > 0)
                break;
        }

        send_pending(client_sock, context);

        if (read_size > 0) {
            fprintf(stderr, "USED CIPHER: %s\n", tls_cipher_name(context));
            int ref_packet_count = 0;
            int res;
            while ((read_size = recv(client_sock, client_message, sizeof(client_message) , 0)) > 0) {
                if (tls_consume_stream(context, client_message, read_size, verify_signature) < 0) {
                    fprintf(stderr, "Error in stream consume\n");
                    break;
                }
                send_pending(client_sock, context);
                if (tls_established(context) == 1) {
                    unsigned char read_buffer[0xFFFF];
                    int read_size = tls_read(context, read_buffer, sizeof(read_buffer) - 1);
                    if (read_size > 0) {
                        read_buffer[read_size] = 0;
                        unsigned char export_buffer[0xFFF];
                        // simulate serialization / deserialization to another process
                        char sni[0xFF];
                        sni[0] = 0;
                        if (context->sni)
                            snprintf(sni, 0xFF, "%s", context->sni);
    /* COOL STUFF => */ int size = tls_export_context(context, export_buffer, sizeof(export_buffer), 1);
                        if (size > 0) {
    /* COOLER STUFF => */   struct TLSContext *imported_context = tls_import_context(export_buffer, size);
    // This is cool because a context can be sent to an existing process.
    // It will work both with fork and with already existing worker process.
                            fprintf(stderr, "Imported context (size: %i): %x\n", size, imported_context);
                            if (imported_context) {
                                // destroy old context
                                tls_destroy_context(context);
                                // simulate serialization/deserialization of context
                                context = imported_context;
                            }
                        }
                        // ugly inefficient code ... don't write like me
                        char send_buffer[0xF000];
                        char send_buffer_with_header[0xF000];
                        char out_buffer[0xFFF];
                        int tls_version = 2;
                        switch (context->version) {
                            case TLS_V10:
                                tls_version = 0;
                                break;
                            case TLS_V11:
                                tls_version = 1;
                                break;
                        }
                        snprintf(send_buffer, sizeof(send_buffer), "Hello world from TLS 1.%i (used chipher is: %s), SNI: %s\r\nYour identity is: %s\r\n\r\nCertificate: %s\r\n\r\nBelow is the received header:\r\n%s\r\nAnd the source code for this example: \r\n\r\n%s", tls_version, tls_cipher_name(context), sni, identity_str, tls_certificate_to_string(server_context->certificates[0], out_buffer, sizeof(out_buffer)), read_buffer, source_buf);
                        int content_length = strlen(send_buffer);
                        snprintf(send_buffer_with_header, sizeof(send_buffer), "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/plain\r\nContent-length: %i\r\n\r\n%s", content_length, send_buffer);
                        tls_write(context, send_buffer_with_header, strlen(send_buffer_with_header));
                        tls_close_notify(context);
                        send_pending(client_sock, context);
                        break;
                    }
                }
            }
        }
#ifdef __WIN32
        shutdown(client_sock, SD_BOTH);
        closesocket(client_sock);
#else
        shutdown(client_sock, SHUT_RDWR);
        close(client_sock);
#endif
        tls_destroy_context(context);
    }
    tls_destroy_context(server_context);
    return 0;
}