static CURLcode set_buffer(struct SessionHandle * data, gsk_handle h, GSK_BUF_ID id, const char * buffer) { int rc = gsk_attribute_set_buffer(h, id, buffer, 0); switch (rc) { case GSK_OK: return CURLE_OK; case GSK_ERROR_IO: failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno)); break; default: failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc)); break; } return CURLE_SSL_CONNECT_ERROR; }
static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h, GSK_BUF_ID id, const char *buffer, bool unsupported_ok) { int rc = gsk_attribute_set_buffer(h, id, buffer, 0); switch (rc) { case GSK_OK: return CURLE_OK; case GSK_ERROR_IO: failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno)); break; case GSK_ATTRIBUTE_INVALID_ID: if(unsupported_ok) return CURLE_UNSUPPORTED_PROTOCOL; default: failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc)); break; } return CURLE_SSL_CONNECT_ERROR; }
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex) { struct SessionHandle * data = conn->data; struct ssl_connect_data * connssl = &conn->ssl[sockindex]; gsk_handle envir; CURLcode cc; int rc; char * keyringfile; char * keyringpwd; char * keyringlabel; char * v2ciphers; char * v3ciphers; char * sni; bool sslv2enable, sslv3enable, tlsv1enable; long timeout; Qso_OverlappedIO_t commarea; /* Create SSL environment, start (preferably asynchronous) handshake. */ connssl->handle = (gsk_handle) NULL; connssl->iocport = -1; /* GSKit supports two ways of specifying an SSL context: either by * application identifier (that should have been defined at the system * level) or by keyring file, password and certificate label. * Local certificate name (CURLOPT_SSLCERT) is used to hold either the * application identifier of the certificate label. * Key password (CURLOPT_KEYPASSWD) holds the keyring password. * It is not possible to have different keyrings for the CAs and the * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify * the keyring file. * If no key password is given and the keyring is the system keyring, * application identifier mode is tried first, as recommended in IBM doc. */ keyringfile = data->set.str[STRING_SSL_CAFILE]; keyringpwd = data->set.str[STRING_KEY_PASSWD]; keyringlabel = data->set.str[STRING_CERT]; envir = (gsk_handle) NULL; if(keyringlabel && *keyringlabel && !keyringpwd && !strcmp(keyringfile, CURL_CA_BUNDLE)) { /* Try application identifier mode. */ init_environment(data, &envir, keyringlabel, (const char *) NULL, (const char *) NULL, (const char *) NULL); } if(!envir) { /* Use keyring mode. */ cc = init_environment(data, &envir, (const char *) NULL, keyringfile, keyringlabel, keyringpwd); if(cc != CURLE_OK) return cc; } /* Create secure session. */ cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle), "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR); gsk_environment_close(&envir); if(cc != CURLE_OK) return cc; /* Determine which SSL/TLS version should be enabled. */ sslv2enable = sslv3enable = tlsv1enable = false; sni = conn->host.name; switch (data->set.ssl.version) { case CURL_SSLVERSION_SSLv2: sslv2enable = true; sni = (char *) NULL; break; case CURL_SSLVERSION_SSLv3: sslv3enable = true; sni = (char *) NULL; break; case CURL_SSLVERSION_TLSv1: tlsv1enable = true; break; default: /* CURL_SSLVERSION_DEFAULT. */ sslv3enable = true; tlsv1enable = true; break; } /* Process SNI. Ignore if not supported (on OS400 < V7R1). */ if(sni) { rc = gsk_attribute_set_buffer(connssl->handle, GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0); switch (rc) { case GSK_OK: case GSK_ATTRIBUTE_INVALID_ID: break; case GSK_ERROR_IO: failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno)); cc = CURLE_SSL_CONNECT_ERROR; break; default: failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc)); cc = CURLE_SSL_CONNECT_ERROR; break; } } /* Set session parameters. */ if(cc == CURLE_OK) { /* Compute the handshake timeout. Since GSKit granularity is 1 second, we round up the required value. */ timeout = Curl_timeleft(data, NULL, TRUE); if(timeout < 0) cc = CURLE_OPERATION_TIMEDOUT; else cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT, (timeout + 999) / 1000); } if(cc == CURLE_OK) cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]); if(cc == CURLE_OK) cc = set_ciphers(data, connssl->handle); if(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2, sslv2enable? GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF); if(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3, sslv3enable? GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF); if(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1, sslv3enable? GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF); if(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE, data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL: GSK_SERVER_AUTH_PASSTHRU); if(cc == CURLE_OK) { /* Start handshake. Try asynchronous first. */ memset(&commarea, 0, sizeof commarea); connssl->iocport = QsoCreateIOCompletionPort(); if(connssl->iocport != -1) { cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle, connssl->iocport, &commarea), "gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) { connssl->connecting_state = ssl_connect_2; return CURLE_OK; } else close_async_handshake(connssl); } else if(errno != ENOBUFS) cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0); else { /* No more completion port available. Use synchronous IO. */ cc = gskit_status(data, gsk_secure_soc_init(connssl->handle), "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) { connssl->connecting_state = ssl_connect_3; return CURLE_OK; } } } /* Error: rollback. */ close_one(connssl, data); return cc; }
void main(void) { gsk_handle my_env_handle=NULL; /* secure environment handle */ gsk_handle my_session_handle=NULL; /* secure session handle */ struct sockaddr_in address; int buf_len, rc = 0, sd = -1; int amtWritten, amtRead; char buff1[1024]; char buff2[1024]; /* hardcoded IP address (change to make address where server program runs) */ #pragma convert(37) char addr[16] = "129.142.220.37"; /*********************************************/ #pragma convert(0) /* Issue all of the command in a do/while */ /* loop so that cleanup can happen at end */ /*********************************************/ do { /* open a gsk environment */ rc = errno = 0; rc = gsk_environment_open(&my_env_handle); if (rc != GSK_OK) { printf("gsk_environment_open() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* set the Application ID to use */ rc = errno = 0; #pragma convert(37) rc = gsk_attribute_set_buffer(my_env_handle, GSK_OS400_APPLICATION_ID, "PYTHON", 6); #pragma convert(0) if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* set this side as the client (this is the default */ rc = errno = 0; rc = gsk_attribute_set_enum(my_env_handle, GSK_SESSION_TYPE, GSK_CLIENT_SESSION); if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* by default SSL_V2, SSL_V3, and TLS_V1 are enabled */ /* We will disable SSL_V2 for this example. */ /*rc = errno = 0; rc = gsk_attribute_set_enum(my_env_handle, GSK_PROTOCOL_SSLV2, GSK_PROTOCOL_SSLV2_OFF); if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; }*/ /* set the cipher suite to use. By default our default list */ /* of ciphers is enabled. For this example we will just use one */ /*rc = errno = 0; rc = gsk_attribute_set_buffer(my_env_handle, GSK_V3_CIPHER_SPECS, "05", 2); if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; }*/ /* Initialize the secure environment */ rc = errno = 0; rc = gsk_environment_init(my_env_handle); if (rc != GSK_OK) { printf("gsk_environment_init() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* initialize a socket to be used for listening */ sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { perror("socket() failed"); break; } /* connect to the server using a set port number */ memset((char *) &address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = 443; address.sin_addr.s_addr = inet_addr(addr); rc = connect(sd, (struct sockaddr *) &address, sizeof(address)); if (rc < 0) { perror("connect() failed"); break; } /* open a secure session */ rc = errno = 0; rc = gsk_secure_soc_open(my_env_handle, &my_session_handle); if (rc != GSK_OK) { printf("gsk_secure_soc_open() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* associate our socket with the secure session */ rc=errno=0; rc = gsk_attribute_set_numeric_value(my_session_handle, GSK_FD, sd); if (rc != GSK_OK) { printf("gsk_attribute_set_numeric_value() failed with rc = %d ", rc); printf("and errno = %d.\n", errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* initiate the SSL handshake */ rc = errno = 0; rc = gsk_secure_soc_init(my_session_handle); if (rc != GSK_OK) { #pragma convert(37) /*printf("gsk_secure_soc_init() failed with rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc));*/ #pragma convert(0) break; } /* memset buffer to hex zeros */ memset((char *) buff1, 0, sizeof(buff1)); /* send a message to the server using the secure session */ strcpy(buff1,"Test of gsk_secure_soc_write \n\n"); /* send the message to the client using the secure session */ buf_len = strlen(buff1); amtWritten = 0; rc = gsk_secure_soc_write(my_session_handle, buff1, buf_len, &amtWritten); if (amtWritten != buf_len) { if (rc != GSK_OK) { printf("gsk_secure_soc_write() rc = %d and errno = %d.\n",rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } else { printf("gsk_secure_soc_write() did not write all data.\n"); break; } } /* write results to screen */ printf("gsk_secure_soc_write() wrote %d bytes...\n", amtWritten); printf("%s\n",buff1); /* memset buffer to hex zeros */ memset((char *) buff2, 0x00, sizeof(buff2)); /* receive a message from the client using the secure session */ amtRead = 0; rc = gsk_secure_soc_read(my_session_handle, buff2, sizeof(buff2), &amtRead); if (rc != GSK_OK) { printf("gsk_secure_soc_read() rc = %d and errno = %d.\n",rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* write results to screen */ printf("gsk_secure_soc_read() received %d bytes, here they are ...\n", amtRead); printf("%s\n",buff2); } while(FALSE); /* disable SSL support for the socket */ if (my_session_handle != NULL) gsk_secure_soc_close(&my_session_handle); /* disable the SSL environment */ if (my_env_handle != NULL) gsk_environment_close(&my_env_handle); /* close the connection */ if (sd > -1) close(sd); return; }