VirtualBox

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

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

IPRT,QtGui: Redid the certificate download code in the GUI and reduced the number of unnecessary wrapper methods. Removed RTHttpCertDigest, adding RTHttpFreeResponse and RTHttpFreeResponseText. Also added RTCrPemParseContent.

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