客户端代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#include
<stdio.h> #include
<errno.h> #include
<unistd.h> #include
<malloc.h> #include
<string.h> #include
<sys/socket.h> #include
<resolv.h> #include
<netdb.h> #include
<openssl/ssl.h> #include
<openssl/err.h> #define
FAIL -1 int OpenConnection( const char *hostname, int port) { int sd; struct hostent
*host; struct sockaddr_in
addr; if (
(host = gethostbyname(hostname)) == NULL ) { printf ( 'Eroor:
%s\n' ,hostname); perror (hostname); abort (); } sd
= socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof (addr)); addr.sin_family
= AF_INET; addr.sin_port
= htons(port); addr.sin_addr.s_addr
= *( long *)(host->h_addr); if (
connect(sd, ( struct sockaddr*)&addr, sizeof (addr))
!= 0 ) { close(sd); perror (hostname); abort (); } return sd; } SSL_CTX*
InitCTX( void ) {
SSL_METHOD *method; SSL_CTX
*ctx; OpenSSL_add_all_algorithms(); /*
Load cryptos, et.al. */ SSL_load_error_strings(); /*
Bring in and register error messages */ method
= SSLv2_client_method(); /*
Create new client-method instance */ ctx
= SSL_CTX_new(method); /*
Create new context */ if (
ctx == NULL ) { ERR_print_errors_fp(stderr); printf ( 'Eroor:
%s\n' ,stderr); abort (); } return ctx; } void ShowCerts(SSL*
ssl) {
X509 *cert; char *line; cert
= SSL_get_peer_certificate(ssl); /*
get the server's certificate */ if (
cert != NULL ) { printf ( "Server
certificates:\n" ); line
= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf ( "Subject:
%s\n" ,
line); free (line); /*
free the malloc'ed string */ line
= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf ( "Issuer:
%s\n" ,
line); free (line); /*
free the malloc'ed string */ X509_free(cert); /*
free the malloc'ed certificate copy */ } else printf ( "No
certificates.\n" ); } int main( int count, char *strings[]) {
SSL_CTX *ctx; int server; SSL
*ssl; char buf[1024]; int bytes; char *hostname,
*portnum; if (
count != 3 ) { printf ( "usage:
%s <hostname> <portnum>\n" ,
strings[0]); exit (0); } SSL_library_init(); hostname=strings[1]; portnum=strings[2]; ctx
= InitCTX(); server
= OpenConnection(hostname, atoi (portnum)); ssl
= SSL_new(ctx); /*
create new SSL connection state */ SSL_set_fd(ssl,
server); /*
attach the socket descriptor */ if (
SSL_connect(ssl) == FAIL ) /*
perform the connection */ { printf ( 'Eroor:
%s\n' ,stderr); ERR_print_errors_fp(stderr); } else { char *msg
= "HelloWorld" ; printf ( "Connected
with %s encryption\n" ,
SSL_get_cipher(ssl)); ShowCerts(ssl); /*
get any certs */ SSL_write(ssl,
msg, strlen (msg)); /*
encrypt & send message */ bytes
= SSL_read(ssl, buf, sizeof (buf)); /*
get reply & decrypt */ buf[bytes]
= 0; printf ( "Received:
\"%s\"\n" ,
buf); SSL_free(ssl); /*
release connection state */ } close(server); /*
close socket */ SSL_CTX_free(ctx); /*
release context */ return 0; } |
服务端代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#include
<errno.h> #include
<unistd.h> #include
<malloc.h> #include
<string.h> #include
<arpa/inet.h> #include
<sys/socket.h> #include
<sys/types.h> #include
<netinet/in.h> #include
<resolv.h> #include
"openssl/ssl.h" #include
"openssl/err.h" #define
FAIL -1 using namespace std; int OpenListener( int port) { int sd; struct sockaddr_in
addr; sd
= socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof (addr)); addr.sin_family
= AF_INET; addr.sin_port
= htons(port); addr.sin_addr.s_addr
= INADDR_ANY; if (
bind(sd, ( struct sockaddr*)&addr, sizeof (addr))
!= 0 ) { perror ( "can't
bind port" ); abort (); } if (
listen(sd, 10) != 0 ) { perror ( "Can't
configure listening port" ); abort (); } return sd; } SSL_CTX*
InitServerCTX( void ) { SSL_CTX
*ctx = NULL; #if
OPENSSL_VERSION_NUMBER >= 0x10000000L const SSL_METHOD
*method; #else SSL_METHOD
*method; #endif SSL_library_init(); OpenSSL_add_all_algorithms(); /*
load & register all cryptos, etc. */ SSL_load_error_strings(); /*
load all error messages */ method
= SSLv23_client_method(); /*
create new server-method instance */ ctx
= SSL_CTX_new(method); /*
create new context from method */ if (
ctx == NULL ) { ERR_print_errors_fp(stderr); abort (); } return ctx; } void LoadCertificates(SSL_CTX*
ctx, char *
CertFile, char *
KeyFile) { //New
lines if (SSL_CTX_load_verify_locations(ctx,
CertFile, KeyFile) != 1) ERR_print_errors_fp(stderr); if (SSL_CTX_set_default_verify_paths(ctx)
!= 1) ERR_print_errors_fp(stderr); //End
new lines /*
set the local certificate from CertFile */ if (
SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); abort (); } /*
set the private key from KeyFile (may be the same as CertFile) */ if (
SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); abort (); } /*
verify private key */ if (
!SSL_CTX_check_private_key(ctx) ) { fprintf (stderr, "Private
key does not match the public certificate\n" ); abort (); } printf ( "LoadCertificates
Compleate Successfully.....\n" ); } void ShowCerts(SSL*
ssl) {
X509 *cert; char *line; cert
= SSL_get_peer_certificate(ssl); /*
Get certificates (if available) */ if (
cert != NULL ) { printf ( "Server
certificates:\n" ); line
= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf ( "Subject:
%s\n" ,
line); free (line); line
= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf ( "Issuer:
%s\n" ,
line); free (line); X509_free(cert); } else printf ( "No
certificates.\n" ); } void Servlet(SSL*
ssl) /*
Serve the connection -- threadable */ { char buf[1024]; char reply[1024]; int sd,
bytes; const char *
HTMLecho= "<html><body><pre>%s</pre></body></html>\n\n" ; if (
SSL_accept(ssl) == FAIL ) /*
do SSL-protocol accept */ ERR_print_errors_fp(stderr); else { ShowCerts(ssl); /*
get any certificates */ bytes
= SSL_read(ssl, buf, sizeof (buf)); /*
get request */ if (
bytes > 0 ) { buf[bytes]
= 0; printf ( "Client
msg: \"%s\"\n" ,
buf); sprintf (reply,
HTMLecho, buf); /*
construct reply */ SSL_write(ssl,
reply, strlen (reply)); /*
send reply */ } else ERR_print_errors_fp(stderr); } sd
= SSL_get_fd(ssl); /*
get socket connection */ SSL_free(ssl); /*
release SSL state */ close(sd); /*
close connection */ } int main( int count, char *strings[]) {
SSL_CTX *ctx; int server; char *portnum; if (
count != 2 ) { printf ( "Usage:
%s <portnum>\n" ,
strings[0]); exit (0); } else { printf ( "Usage:
%s <portnum>\n" ,
strings[1]); } SSL_library_init(); portnum
= strings[1]; ctx
= InitServerCTX(); /*
initialize SSL */ LoadCertificates(ctx, "/home/stud/kawsar/mycert.pem" , "/home/stud/kawsar/mycert.pem" ); /*
load certs */ server
= OpenListener( atoi (portnum)); /*
create server socket */ while (1) { struct sockaddr_in
addr; socklen_t
len = sizeof (addr); SSL
*ssl; int client
= accept(server, ( struct sockaddr*)&addr,
&len); /*
accept connection as usual */ printf ( "Connection:
%s:%d\n" ,inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port)); ssl
= SSL_new(ctx); /*
get new SSL state with context */ SSL_set_fd(ssl,
client); /*
set connection socket to SSL state */ Servlet(ssl); /*
service connection */ } close(server); /*
close server socket */ SSL_CTX_free(ctx); /*
release context */ } |