s32 ssl_new(u8 * CN, u32 ssl_verify_options){ s32 ret; s32 aContext[8] ATTRIBUTE_ALIGN(32); u32 aVerify_options[8] ATTRIBUTE_ALIGN(32); ret = ssl_open(); if(ret){ return ret; } aVerify_options[0] = ssl_verify_options; if(ISALIGNED(CN)){ //Avoid alignment if the input is aligned ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_NEW, "d:dd", aContext, 0x20, aVerify_options, 0x20, CN, 0x100); }else{ u8 *aCN = NULL; aCN = iosAlloc(__ssl_hid, 0x100); if (!aCN) { return IPC_ENOMEM; } memcpy(aCN, CN, 0x100); ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_NEW, "d:dd", aContext, 0x20, aVerify_options, 0x20, aCN, 0x100); if(aCN){ iosFree(__ssl_hid, aCN); } } ssl_close(); return (ret ? ret : aContext[0]); }
s32 ssl_read(s32 ssl_context, void* buffer, s32 length){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } if(!buffer){ return IPC_EINVAL; } u8 *aBuffer = NULL; aBuffer = iosAlloc(__ssl_hid, length); if (!aBuffer) { return IPC_ENOMEM; } aSsl_context[0] = ssl_context; ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_READ, "dd:d", aResponse, 0x20, aBuffer, length, aSsl_context, 0x20); ssl_close(); if(ret == IPC_OK){ memcpy(buffer, aBuffer, aResponse[0]); } if(aBuffer){ iosFree(__ssl_hid, aBuffer); } return (ret ? ret : aResponse[0]); }
s32 ssl_write(s32 ssl_context, const void *buffer, s32 length){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } if(!buffer){ return IPC_EINVAL; } aSsl_context[0] = ssl_context; if(ISALIGNED(buffer)){ //Avoid alignment if the input is aligned ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_WRITE, "d:dd", aResponse, 0x20, aSsl_context, 0x20, buffer, length); }else{ u8 *aBuffer = NULL; aBuffer = iosAlloc(__ssl_hid, length); if (!aBuffer) { return IPC_ENOMEM; } memcpy(aBuffer, buffer, length); ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_WRITE, "d:dd", aResponse, 0x20, aSsl_context, 0x20, aBuffer, length); } ssl_close(); return (ret ? ret : aResponse[0]); }
s32 ssl_setrootca(s32 ssl_context, const void *root, u32 length){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } aSsl_context[0] = ssl_context; if(ISALIGNED(root)){ //Avoid alignment if the input is aligned ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_SETROOTCA, "d:dd", aResponse, 0x20, aSsl_context, 0x20, root, length); }else{ u8 *aRoot = NULL; aRoot = iosAlloc(__ssl_hid, length); if (!aRoot) { return IPC_ENOMEM; } memcpy(aRoot, root, length); ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_SETROOTCA, "d:dd", aResponse, 0x20, aSsl_context, 0x20, aRoot, length); if(aRoot){ iosFree(__ssl_hid, aRoot); } } ssl_close(); return (ret ? ret : aResponse[0]); }
/* ** Open a connection to the server. The server is defined by the following ** variables: ** ** pUrlData->name Name of the server. Ex: www.fossil-scm.org ** pUrlData->port TCP/IP port. Ex: 80 ** pUrlData->isHttps Use TLS for the connection ** ** Return the number of errors. */ int transport_open(UrlData *pUrlData){ int rc = 0; if( transport.isOpen==0 ){ if( pUrlData->isSsh ){ rc = transport_ssh_open(pUrlData); if( rc==0 ) transport.isOpen = 1; }else if( pUrlData->isHttps ){ #ifdef FOSSIL_ENABLE_SSL rc = ssl_open(pUrlData); if( rc==0 ) transport.isOpen = 1; #else socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support"); rc = 1; #endif }else if( pUrlData->isFile ){ sqlite3_uint64 iRandId; sqlite3_randomness(sizeof(iRandId), &iRandId); transport.zOutFile = mprintf("%s-%llu-out.http", g.zRepositoryName, iRandId); transport.zInFile = mprintf("%s-%llu-in.http", g.zRepositoryName, iRandId); transport.pFile = fossil_fopen(transport.zOutFile, "wb"); if( transport.pFile==0 ){ fossil_fatal("cannot output temporary file: %s", transport.zOutFile); } transport.isOpen = 1; }else{ rc = socket_open(pUrlData); if( rc==0 ) transport.isOpen = 1; } } return rc; }
s32 ssl_handshake( s32 ssl_context ){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } aSsl_context[0] = ssl_context; ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_HANDSHAKE, "d:d", aResponse, 0x20, aSsl_context, 0x20); ssl_close(); return (ret ? ret : aResponse[0]); }
s32 ssl_connect(s32 ssl_context, s32 socket){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aSocket[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } aSsl_context[0] = ssl_context; aSocket[0] = socket; ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_CONNECT, "d:dd", aResponse, 0x20, aSsl_context, 0x20, aSocket, 0x20); ssl_close(); return (ret ? ret : aResponse[0]); }
s32 ssl_setbuiltinclientcert(s32 ssl_context, s32 index){ s32 aSsl_context[8] ATTRIBUTE_ALIGN(32); s32 aIndex[8] ATTRIBUTE_ALIGN(32); s32 aResponse[8] ATTRIBUTE_ALIGN(32); s32 ret; ret = ssl_open(); if(ret){ return ret; } aSsl_context[0] = ssl_context; aIndex[0] = index; ret = IOS_IoctlvFormat(__ssl_hid, __ssl_fd, IOCTLV_SSL_SETBUILTINCLIENTCERT, "d:dd", aResponse, 32, aSsl_context, 32, aIndex, 32); ssl_close(); return (ret ? ret : aResponse[0]); }
/* Sets up the object. */ int http_init(http_t *client, char *msg) { int rc = 0; do { TRY(local_set_params(client)); TRY(ssl_open(client, msg)); } while (0); if (rc) { http_exit(client); return rc; } client->initialized = 1; return 0; }
/* ** Open a connection to the server. The server is defined by the following ** global variables: ** ** g.urlName Name of the server. Ex: www.fossil-scm.org ** g.urlPort TCP/IP port. Ex: 80 ** g.urlIsHttps Use TLS for the connection ** ** Return the number of errors. */ int transport_open(void){ int rc = 0; if( transport.isOpen==0 ){ if( g.urlIsSsh ){ Blob cmd; blob_zero(&cmd); shell_escape(&cmd, g.urlFossil); blob_append(&cmd, " test-http ", -1); shell_escape(&cmd, g.urlPath); /* fprintf(stdout, "%s\n", blob_str(&cmd)); */ fprintf(sshOut, "%s\n", blob_str(&cmd)); fflush(sshOut); blob_reset(&cmd); }else if( g.urlIsHttps ){ #ifdef FOSSIL_ENABLE_SSL rc = ssl_open(); if( rc==0 ) transport.isOpen = 1; #else socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support"); rc = 1; #endif }else if( g.urlIsFile ){ sqlite3_uint64 iRandId; sqlite3_randomness(sizeof(iRandId), &iRandId); transport.zOutFile = mprintf("%s-%llu-out.http", g.zRepositoryName, iRandId); transport.zInFile = mprintf("%s-%llu-in.http", g.zRepositoryName, iRandId); transport.pFile = fopen(transport.zOutFile, "wb"); if( transport.pFile==0 ){ fossil_fatal("cannot output temporary file: %s", transport.zOutFile); } transport.isOpen = 1; }else{ rc = socket_open(); if( rc==0 ) transport.isOpen = 1; } } return rc; }