VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTHttp.cpp@ 57358

Last change on this file since 57358 was 57358, checked in by vboxsync, 9 years ago

*: scm cleanup run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/* $Id: tstRTHttp.cpp 57358 2015-08-14 15:16:38Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Simple cURL testcase.
4 */
5
6/*
7 * Copyright (C) 2012-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/err.h>
32#include <iprt/http.h>
33#include <iprt/mem.h>
34#include <iprt/file.h>
35#include <iprt/stream.h>
36#include <iprt/string.h>
37#include <iprt/initterm.h>
38#include <iprt/vfslowlevel.h>
39#include <iprt/zip.h>
40
41#define CAFILE_NAME "tstHttp-tempcafile.crt"
42
43static int extractPCA3G5(RTHTTP hHttp, PRTSTREAM CAFile, uint8_t *pu8Buf, size_t cbBuf)
44{
45 uint8_t *abSha1;
46 size_t cbSha1;
47 uint8_t *abSha512;
48 size_t cbSha512;
49 char *pszBuf = (char*)pu8Buf;
50
51 const uint8_t abSha1PCA3G5[] =
52 {
53 0x4e, 0xb6, 0xd5, 0x78, 0x49, 0x9b, 0x1c, 0xcf, 0x5f, 0x58,
54 0x1e, 0xad, 0x56, 0xbe, 0x3d, 0x9b, 0x67, 0x44, 0xa5, 0xe5
55 };
56 const uint8_t abSha512PCA3G5[] =
57 {
58 0xd4, 0xf8, 0x10, 0x54, 0x72, 0x77, 0x0a, 0x2d,
59 0xe3, 0x17, 0xb3, 0xcf, 0xed, 0x61, 0xae, 0x5c,
60 0x5d, 0x3e, 0xde, 0xa1, 0x41, 0x35, 0xb2, 0xdf,
61 0x60, 0xe2, 0x61, 0xfe, 0x3a, 0xc1, 0x66, 0xa3,
62 0x3c, 0x88, 0x54, 0x04, 0x4f, 0x1d, 0x13, 0x46,
63 0xe3, 0x8c, 0x06, 0x92, 0x9d, 0x70, 0x54, 0xc3,
64 0x44, 0xeb, 0x2c, 0x74, 0x25, 0x9e, 0x5d, 0xfb,
65 0xd2, 0x6b, 0xa8, 0x9a, 0xf0, 0xb3, 0x6a, 0x01
66 };
67 int rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf,
68 &abSha1, &cbSha1, &abSha512, &cbSha512);
69 if (RT_SUCCESS(rc))
70 {
71 if (cbSha1 != sizeof(abSha1PCA3G5))
72 {
73 RTPrintf("Wrong SHA1 digest size of PCA-3G5\n");
74 rc = VERR_INTERNAL_ERROR;
75 }
76 else if (memcmp(abSha1PCA3G5, abSha1, cbSha1))
77 {
78 RTPrintf("Wrong SHA1 digest for PCA-3G5:\n"
79 "Got: %.*Rhxs\n"
80 "Expected: %.*Rhxs\n",
81 cbSha1, abSha1, sizeof(abSha1PCA3G5), abSha1PCA3G5);
82 rc = VERR_INTERNAL_ERROR;
83 }
84 if (cbSha512 != sizeof(abSha512PCA3G5))
85 {
86 RTPrintf("Wrong SHA512 digest size of PCA-3G5\n");
87 rc = VERR_INTERNAL_ERROR;
88 }
89 else if (memcmp(abSha512PCA3G5, abSha512, cbSha512))
90 {
91 RTPrintf("Wrong SHA512 digest for PCA-3G5:\n"
92 "Got: %.*Rhxs\n"
93 "Expected: %.*Rhxs\n",
94 cbSha512, abSha512, sizeof(abSha512PCA3G5), abSha512PCA3G5);
95 rc = VERR_INTERNAL_ERROR;
96 }
97 RTMemFree(abSha1);
98 RTMemFree(abSha512);
99 if (RT_SUCCESS(rc))
100 rc = RTStrmWrite(CAFile, pszBuf, cbBuf);
101 if (RT_SUCCESS(rc))
102 rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
103 }
104 return rc;
105}
106
107static int extractPCA3(RTHTTP hHttp, PRTSTREAM CAFile, uint8_t *pu8Buf, size_t cbBuf)
108{
109 uint8_t *abSha1;
110 size_t cbSha1;
111 uint8_t *abSha512;
112 size_t cbSha512;
113 char *pszBuf = (char*)pu8Buf;
114
115 const uint8_t abSha1PCA3[] =
116 {
117 0xa1, 0xdb, 0x63, 0x93, 0x91, 0x6f, 0x17, 0xe4, 0x18, 0x55,
118 0x09, 0x40, 0x04, 0x15, 0xc7, 0x02, 0x40, 0xb0, 0xae, 0x6b
119 };
120 const uint8_t abSha512PCA3[] =
121 {
122 0xbb, 0xf7, 0x8a, 0x19, 0x9f, 0x37, 0xee, 0xa2,
123 0xce, 0xc8, 0xaf, 0xe3, 0xd6, 0x22, 0x54, 0x20,
124 0x74, 0x67, 0x6e, 0xa5, 0x19, 0xb7, 0x62, 0x1e,
125 0xc1, 0x2f, 0xd5, 0x08, 0xf4, 0x64, 0xc4, 0xc6,
126 0xbb, 0xc2, 0xf2, 0x35, 0xe7, 0xbe, 0x32, 0x0b,
127 0xde, 0xb2, 0xfc, 0x44, 0x92, 0x5b, 0x8b, 0x9b,
128 0x77, 0xa5, 0x40, 0x22, 0x18, 0x12, 0xcb, 0x3d,
129 0x0a, 0x67, 0x83, 0x87, 0xc5, 0x45, 0xc4, 0x99
130 };
131 int rc = RTHttpCertDigest(hHttp, pszBuf, cbBuf,
132 &abSha1, &cbSha1, &abSha512, &cbSha512);
133 if (RT_SUCCESS(rc))
134 {
135 if (cbSha1 != sizeof(abSha1PCA3))
136 {
137 RTPrintf("Wrong SHA1 digest size of PCA-3\n");
138 rc = VERR_INTERNAL_ERROR;
139 }
140 else if (memcmp(abSha1PCA3, abSha1, cbSha1))
141 {
142 RTPrintf("Wrong SHA1 digest for PCA-3:\n"
143 "Got: %.*Rhxs\n"
144 "Expected: %.*Rhxs\n",
145 cbSha1, abSha1, sizeof(abSha1PCA3), abSha1PCA3);
146 rc = VERR_INTERNAL_ERROR;
147 }
148 if (cbSha512 != sizeof(abSha512PCA3))
149 {
150 RTPrintf("Wrong SHA512 digest size of PCA-3\n");
151 rc = VERR_INTERNAL_ERROR;
152 }
153 else if (memcmp(abSha512PCA3, abSha512, cbSha512))
154 {
155 RTPrintf("Wrong SHA512 digest for PCA-3:\n"
156 "Got: %.*Rhxs\n"
157 "Expected: %.*Rhxs\n",
158 cbSha512, abSha512, sizeof(abSha512PCA3), abSha512PCA3);
159 rc = VERR_INTERNAL_ERROR;
160 }
161 RTMemFree(abSha1);
162 RTMemFree(abSha512);
163 if (RT_SUCCESS(rc))
164 rc = RTStrmWrite(CAFile, pszBuf, cbBuf);
165 if (RT_SUCCESS(rc))
166 rc = RTStrmWrite(CAFile, RTFILE_LINEFEED, strlen(RTFILE_LINEFEED));
167 }
168
169 return rc;
170}
171
172/*
173 * Check for HTTP errors, in particular properly display redirections.
174 */
175static void checkError(RTHTTP hHttp, int rc, const char *pszFile)
176{
177 if (rc == VERR_HTTP_REDIRECTED)
178 {
179 char *pszRedirLocation;
180 int rc2 = RTHttpGetRedirLocation(hHttp, &pszRedirLocation);
181 if (RT_SUCCESS(rc2))
182 RTPrintf("Redirected to '%s' trying to fetch '%s'\n", pszRedirLocation, pszFile);
183 else
184 RTPrintf("Redirected trying to fetch '%s'\n", pszFile);
185 RTStrFree(pszRedirLocation);
186 }
187 else
188 RTPrintf("Error %Rrc trying to fetch '%s'\n", rc, pszFile);
189}
190
191int main(int argc, char **argv)
192{
193 unsigned cErrors = 0;
194
195 RTR3InitExe(argc, &argv, 0);
196
197 if (argc <= 1)
198 {
199 RTPrintf("usage: %s default\n", argv[0]);
200 return 1;
201 }
202
203 for (int i = 1; i < argc; i++)
204 {
205 if (!strcmp(argv[i], "default"))
206 ;
207 else
208 {
209 RTPrintf("Unknown parameter '%s'\n", argv[i]);
210 return 1;
211 }
212 }
213
214 RTHTTP hHttp;
215 char *pszBuf = NULL;
216 PRTSTREAM CAFile = NULL;
217
218 int rc = RTHttpCreate(&hHttp);
219
220 /*
221 * Create the certificate file
222 */
223 if (RT_SUCCESS(rc))
224 rc = RTStrmOpen(CAFILE_NAME, "w+b", &CAFile);
225
226 if (RT_SUCCESS(rc))
227 {
228 /*
229 * The old way:
230 */
231
232 /*
233 * Fetch the root CA certificate (new one, often avoided in cert chains by
234 * using an intermediate cert which is signed by old root)
235 */
236 if (RT_SUCCESS(rc))
237 rc = RTHttpGetText(hHttp,
238 "http://www.verisign.com/repository/roots/root-certificates/PCA-3G5.pem",
239 &pszBuf);
240 if (RT_SUCCESS(rc) && pszBuf)
241 rc = extractPCA3G5(hHttp, CAFile, (uint8_t*)pszBuf, strlen(pszBuf));
242 else
243 checkError(hHttp, rc, "PCA-3G5.pem");
244 if (pszBuf)
245 {
246 RTMemFree(pszBuf);
247 pszBuf = NULL;
248 }
249
250 /*
251 * Fetch the root CA certificate (old one, but still very widely used)
252 */
253 if (RT_SUCCESS(rc))
254 rc = RTHttpGetText(hHttp,
255 "http://www.verisign.com/repository/roots/root-certificates/PCA-3.pem",
256 &pszBuf);
257 if (RT_SUCCESS(rc) && pszBuf)
258 rc = extractPCA3(hHttp, CAFile, (uint8_t*)pszBuf, strlen(pszBuf));
259 else
260 checkError(hHttp, rc, "PCA-3.pem");
261 if (pszBuf)
262 {
263 RTMemFree(pszBuf);
264 pszBuf = NULL;
265 }
266 RTPrintf("Old way: rc=%Rrc\n", rc);
267
268 /*
269 * The new way:
270 */
271 void *pu8Buf;
272 size_t cb;
273 rc = RTHttpGetBinary(hHttp,
274 "http://www.verisign.com/support/roots.zip",
275 &pu8Buf, &cb);
276 if (RT_SUCCESS(rc) && pu8Buf)
277 {
278 void *pvDecomp;
279 size_t cbDecomp;
280 rc = RTZipPkzipMemDecompress(&pvDecomp, &cbDecomp, pu8Buf, cb,
281 "VeriSign Root Certificates/Generation 5 (G5) PCA/VeriSign Class 3 Public Primary Certification Authority - G5.pem");
282 if (RT_SUCCESS(rc))
283 {
284 rc = extractPCA3G5(hHttp, CAFile, (uint8_t*)pvDecomp, cbDecomp);
285 RTMemFree(pvDecomp);
286 rc = RTZipPkzipMemDecompress(&pvDecomp, &cbDecomp, pu8Buf, cb,
287 "VeriSign Root Certificates/Generation 1 (G1) PCAs/Class 3 Public Primary Certification Authority.pem");
288 if (RT_SUCCESS(rc))
289 {
290 rc = extractPCA3(hHttp, CAFile, (uint8_t*)pvDecomp, cbDecomp);
291 RTMemFree(pvDecomp);
292 }
293 }
294 }
295 else
296 checkError(hHttp, rc, "roots.zip");
297 RTPrintf("New way: rc=%Rrc\n", rc);
298 }
299
300 /*
301 * Close the certificate file
302 */
303 if (CAFile)
304 {
305 RTStrmClose(CAFile);
306 CAFile = NULL;
307 }
308
309 /*
310 * Use it
311 */
312 if (RT_SUCCESS(rc))
313 rc = RTHttpSetCAFile(hHttp, CAFILE_NAME);
314
315 /*
316 * Now try to do the actual HTTPS request
317 */
318 if (RT_SUCCESS(rc))
319 rc = RTHttpGetText(hHttp,
320 "https://update.virtualbox.org/query.php?platform=LINUX_32BITS_UBUNTU_12_04&version=4.1.18",
321 &pszBuf);
322
323 if ( RT_FAILURE(rc)
324 && rc != VERR_HTTP_COULDNT_CONNECT)
325 cErrors++;
326
327 if (RT_FAILURE(rc))
328 RTPrintf("Error code: %Rrc\n", rc);
329 else
330 {
331 RTPrintf("Success!\n");
332 RTPrintf("Got: %s\n", pszBuf);
333 }
334 if (pszBuf)
335 {
336 RTMemFree(pszBuf);
337 pszBuf = NULL;
338 }
339
340 RTHttpDestroy(hHttp);
341
342// RTFileDelete(CAFILE_NAME);
343
344 return !!cErrors;
345}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette