Chinaunix首页 | 论坛 | 博客
  • 博客访问: 341299
  • 博文数量: 89
  • 博客积分: 5152
  • 博客等级: 大校
  • 技术积分: 1155
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-25 15:12
文章分类

全部博文(89)

文章存档

2012年(1)

2011年(5)

2010年(14)

2009年(69)

我的朋友

分类: LINUX

2010-10-12 15:15:26

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define RETURN_NULL(x) if ((x)==NULL) exit (1)
#define RETURN_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define RETURN_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(1); }
 
static int verify_callback(int ok, X509_STORE_CTX *ctx);
 
#define RSA_CLIENT_CERT "client.crt"
#define RSA_CLIENT_KEY "client.key"
 
#define RSA_CLIENT_CA_CERT "client_ca.crt"
#define RSA_CLIENT_CA_PATH "sys$common:[syshlp.examples.ssl]"
 
#define ON 1
#define OFF 0
#define MILLION 1000000
const char *url = "/URL";

void main()
{
    int err;
    int verify_client = OFF; /* To verify a client certificate, set ON */
    int sock;
    struct sockaddr_in server_addr;
    char *str;

    SSL_CTX *ctx;
    SSL *ssl;
    SSL_METHOD *meth;
    X509 *server_cert;
    EVP_PKEY    *pkey;
    BIO         *sbio;
    const short int    s_port = 443;    
    const char *s_ipaddr = "127.0.0.1";


    /* Load encryption & hashing algorithms for the SSL program */
    SSL_library_init();

    /* Load the error strings for SSL & CRYPTO APIs */
    SSL_load_error_strings();

    /* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */
    meth = SSLv23_method();

    /* Create an SSL_CTX structure */
    ctx = SSL_CTX_new(meth);

    RETURN_NULL(ctx);
    /*----------------------------------------------------------*/
    if(verify_client == ON)
    {

     /* Load the client certificate into the SSL_CTX structure */
        if (SSL_CTX_use_certificate_file(ctx, RSA_CLIENT_CERT, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            exit(1);
        }

     /* Load the private-key corresponding to the client certificate */
        if (SSL_CTX_use_PrivateKey_file(ctx, RSA_CLIENT_KEY, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            exit(1);
        }

     /* Check if the client certificate and private-key matches */
     if (!SSL_CTX_check_private_key(ctx))
     {
            fprintf(stderr,"Private key does not match the certificate public key\n");
            exit(1);
        }
    }

    /* Load the RSA CA certificate into the SSL_CTX structure */
    /* This will allow this client to verify the server's */
    /* certificate. */


    /* ------------------------------------------------------------- */
    /* Set up a TCP socket */

    sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
    RETURN_ERR(sock, "socket");

    memset (&server_addr, '\0', sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(s_port); /* Server Port number */
    server_addr.sin_addr.s_addr = inet_addr(s_ipaddr); /* Server IP */

    /* Establish a TCP/IP connection to the SSL client */
    err = connect(sock, (struct sockaddr*) &server_addr, sizeof(server_addr));
    RETURN_ERR(err, "connect");
    
    /* ----------------------------------------------- */
    /* An SSL structure is created */
    ssl = SSL_new (ctx);
    sbio=BIO_new_socket(sock,BIO_NOCLOSE);
    SSL_set_bio(ssl,sbio,sbio);
    RETURN_NULL(ssl);
    
    /* Assign the socket into the SSL structure (SSL and socket without BIO) */
    //SSL_set_fd(ssl, sock);

    //printf("SSL_set_fd\n");

    
    /* Perform SSL Handshake on the SSL client */
    err = SSL_connect(ssl);
    RETURN_SSL(err);

    /* Informational output (optional) */
    //printf ("SSL connection using %s\n", SSL_get_cipher (ssl));


    /* Get the server's certificate (optional) */
    /*server_cert = SSL_get_peer_certificate (ssl);

    if (server_cert != NULL)
    {
        printf ("Server certificate:\n");

        str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
        RETURN_NULL(str);
        printf ("\t subject: %s\n", str);
        free (str);

        str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
        RETURN_NULL(str);
        printf ("\t issuer: %s\n", str);
        free(str);

        X509_free (server_cert);

    }
    else
        printf("The SSL server does not have certificate.\n");
    */

    /*-------- DATA EXCHANGE - send message and receive reply. -------*/
    /* Send data to the SSL server */
        //err=SSL_write(ssl,request,request_len);

    char request[2048];
    sprintf(request,"GET %s HTTP/1.1\r\nUser-Agent: Mozilla/5.0 (Linux; X11)\r\nHost: %s\r\n\r\n",
                    url,s_ipaddr);

    err=SSL_write(ssl,request,strlen(request));

    switch(SSL_get_error(ssl,err)){
      case SSL_ERROR_NONE:
        //if(request_len!=err)

        if(strlen(request)!=err)
          printf("Incomplete write! \n");
        break;
        default:
          printf("SSL write problem \n");
    }
    
    RETURN_SSL(err);

    /* Receive data from the SSL server */
    /* Now read the server's response, assuming
       that it's terminated by a close */

    char buf[10000];
    int len = 0;
    while(1)
    {
        err=SSL_read(ssl,buf,10000);
        switch(SSL_get_error(ssl,err)){
        case SSL_ERROR_NONE:
            len=err;
            break;
        case SSL_ERROR_WANT_READ:
            continue;
        case SSL_ERROR_ZERO_RETURN:
            goto done;
        case SSL_ERROR_SYSCALL:
            printf(stderr,"SSL Error: Premature close\n");
            goto done;
        default:
            printf("SSL read problem \n");
        }
        //printf("%s\n",buf);

    }


    /*--------------- SSL closure ---------------*/
    /* Shutdown the client side of the SSL connection */
done:
    
    err = SSL_shutdown(ssl);
    RETURN_SSL(err);

    /* Terminate communication on a socket */
    err = close(sock);

    RETURN_ERR(err, "close");

    /* Free the SSL structure */
    SSL_free(ssl);

    /* Free the SSL_CTX structure */
    SSL_CTX_free(ctx);

}


阅读(976) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-10-13 16:31:30

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com