VirtualBox

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

Last change on this file since 53401 was 51717, checked in by vboxsync, 11 years ago

be a bit more verbose

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