VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTHttp-1.cpp@ 100838

Last change on this file since 100838 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1/* $Id: tstRTHttp-1.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * IPRT - Testcase for the RTHttp API.
4 */
5
6/*
7 * Copyright (C) 2018-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/http.h>
42
43#include <iprt/test.h>
44#include <iprt/message.h>
45#include <iprt/string.h>
46#include <iprt/crypto/key.h>
47
48
49/* Test message:
50 * POST /foo?param=value&pet=dog HTTP/1.1
51 * Host: example.com
52 * Date: Sun, 05 Jan 2014 21:31:40 GMT
53 * Content-Type: application/json
54 * Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
55 * Content-Length: 18
56 *
57 * {"hello": "world"}
58 */
59
60static void testHeaderSigning()
61{
62 static const char s_szPublicKey1[] =
63 "-----BEGIN PUBLIC KEY-----\n"
64 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3\n"
65 "6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6\n"
66 "Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw\n"
67 "oYi+1hqp1fIekaxsyQIDAQAB\n"
68 "-----END PUBLIC KEY-----\n";
69 static const char s_szPrivateKey1[] =
70 "-----BEGIN RSA PRIVATE KEY-----\n"
71 "MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF\n"
72 "NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F\n"
73 "UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB\n"
74 "AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA\n"
75 "QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK\n"
76 "kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg\n"
77 "f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u\n"
78 "412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc\n"
79 "mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7\n"
80 "kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA\n"
81 "gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW\n"
82 "G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI\n"
83 "7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==\n"
84 "-----END RSA PRIVATE KEY-----\n";
85 static const char s_szKeyId1[] = "Test";
86 static const char s_szUrl1[] = "https://example.com/foo?param=value&pet=dog";
87 static const char s_szHost1[] = "example.com";
88 static const char s_szDate1[] = "Sun, 05 Jan 2014 21:31:40 GMT";
89
90 RTTestISub("RTHttpSignHeaders");
91
92
93 /*
94 * Load the key pair used in the reference examples.
95 */
96 RTCRKEY hPublicKey;
97 RTTESTI_CHECK_RC_RETV(RTCrKeyCreateFromBuffer(&hPublicKey, 0, RT_STR_TUPLE(s_szPublicKey1), NULL /*pszPassword*/,
98 NULL /*pErrInfo*/, NULL /*pszErrorTag*/), VINF_SUCCESS);
99 RTCRKEY hPrivateKey;
100 RTTESTI_CHECK_RC_RETV(RTCrKeyCreateFromBuffer(&hPrivateKey, 0, RT_STR_TUPLE(s_szPrivateKey1), NULL /*pszPassword*/,
101 NULL /*pErrInfo*/, NULL /*pszErrorTag*/), VINF_SUCCESS);
102
103 /*
104 * C.2 Basic Test - tweaked a little with 'version="1"'.
105 */
106 RTHTTP hHttp;
107 RTTESTI_CHECK_RC_RETV(RTHttpCreate(&hHttp), VINF_SUCCESS);
108 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Host", RT_STR_TUPLE(s_szHost1), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
109 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Date", RT_STR_TUPLE(s_szDate1), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
110 RTTESTI_CHECK_RC_RETV(RTHttpSignHeaders(hHttp, RTHTTPMETHOD_POST, s_szUrl1, hPrivateKey, s_szKeyId1, 0), VINF_SUCCESS);
111 const char *pszAuth = RTHttpGetHeader(hHttp, RT_STR_TUPLE("Authorization"));
112 RTTESTI_CHECK_RETV(pszAuth);
113 //const char *pszExpect = "Signature keyId=\"Test\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\",signature=\"qdx+H7PHHDZgy4y/Ahn9Tny9V3GP6YgBPyUXMmoxWtLbHpUnXS2mg2+SbrQDMCJypxBLSPQR2aAjn7ndmw2iicw3HMbe8VfEdKFYRqzic+efkb3nndiv/x1xSHDJWeSWkx3ButlYSuBskLu6kd9Fswtemr3lgdDEmn04swr2Os0=\"";
114 const char *pszExpect = "Signature version=\"1\",keyId=\"Test\",algorithm=\"rsa-sha256\","
115 "headers=\"(request-target) host date\","
116 "signature=\"qdx+H7PHHDZgy4y/Ahn9Tny9V3GP6YgBPyUXMmoxWtLbHpUnXS2mg2+SbrQDMCJypxBLSPQR2aAjn7ndmw2iicw3HMbe8VfEdKFYRqzic+efkb3nndiv/x1xSHDJWeSWkx3ButlYSuBskLu6kd9Fswtemr3lgdDEmn04swr2Os0=\"";
117 if (strcmp(pszAuth, pszExpect) != 0)
118 {
119 RTTestIFailed("Test C.2 failed");
120 RTTestIFailureDetails("Got auth: %s\n", pszAuth);
121 RTTestIFailureDetails("Expected: %s\n", pszExpect);
122 }
123 RTTESTI_CHECK_RC(RTHttpDestroy(hHttp), VINF_SUCCESS);
124
125 /*
126 * C.3 All Headers Test - tweaked a little with 'version="1"'.
127 *
128 * Note! Draft #10 has an incorrect signed digest. The decrypting digest
129 * does not match the documented plaintext.
130 * Decrypted sha-256: 407954c106c7e9aa1644fc4764cbfb481cc178dec9142bf62e3cac97251e1953
131 * Plain text sha-256: 53cd4050ff72e3a6383091186168f3df4ca2e6b3a77cbed60a02ba00c9cd8078
132 */
133 hHttp = NIL_RTHTTP;
134 RTTESTI_CHECK_RC_RETV(RTHttpCreate(&hHttp), VINF_SUCCESS);
135 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Host", RT_STR_TUPLE(s_szHost1), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
136 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Date", RT_STR_TUPLE(s_szDate1), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
137 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Content-Type", RT_STR_TUPLE("application/json"), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
138 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Digest", RT_STR_TUPLE("SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE="), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
139 RTTESTI_CHECK_RC_RETV(RTHttpAddHeader(hHttp, "Content-Length", RT_STR_TUPLE("18"), RTHTTPADDHDR_F_BACK), VINF_SUCCESS);
140
141 RTTESTI_CHECK_RC_RETV(RTHttpSignHeaders(hHttp, RTHTTPMETHOD_POST, s_szUrl1, hPrivateKey, s_szKeyId1, 0), VINF_SUCCESS);
142 pszAuth = RTHttpGetHeader(hHttp, RT_STR_TUPLE("Authorization"));
143 RTTESTI_CHECK_RETV(pszAuth);
144 //pszExpect = "Signature keyId=\"Test\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date content-type digest content-length\",signature=\"jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7qnVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0jOyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w=\"";
145 pszExpect = "Signature version=\"1\",keyId=\"Test\",algorithm=\"rsa-sha256\","
146 "headers=\"(request-target) host date content-type digest content-length\","
147 // bad rfc draft #10? "signature=\"jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7qnVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0jOyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w=\"";
148 "signature=\"vSdrb+dS3EceC9bcwHSo4MlyKS59iFIrhgYkz8+oVLEEzmYZZvRs8rgOp+63LEM3v+MFHB32NfpB2bEKBIvB1q52LaEUHFv120V01IL+TAD48XaERZFukWgHoBTLMhYS2Gb51gWxpeIq8knRmPnYePbF5MOkR0Zkly4zKH7s1dE=\"";
149 if (strcmp(pszAuth, pszExpect) != 0)
150 {
151 RTTestIFailed("Test C.3 failed");
152 RTTestIFailureDetails("Got auth: %s\n", pszAuth);
153 RTTestIFailureDetails("Expected: %s\n", pszExpect);
154 }
155
156 RTTESTI_CHECK_RC(RTHttpDestroy(hHttp), VINF_SUCCESS);
157 RTCrKeyRelease(hPublicKey);
158 RTCrKeyRelease(hPrivateKey);
159}
160
161
162int main()
163{
164 RTTEST hTest;
165 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTHttp-1", &hTest);
166 if (rcExit != RTEXITCODE_SUCCESS)
167 return rcExit;
168
169 testHeaderSigning();
170
171 return RTTestSummaryAndDestroy(hTest);
172}
173
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