VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTCrX509-1.cpp@ 76346

Last change on this file since 76346 was 76346, checked in by vboxsync, 6 years ago

*: Preparing for iprt/string.h, iprt/json.h and iprt/serialport.h no longer including iprt/err.h and string.h no longer including latin1.h (it needs err.h). bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: tstRTCrX509-1.cpp 76346 2018-12-22 00:51:28Z vboxsync $ */
2/** @file
3 * IPRT testcase - Crypto - X.509 \#1.
4 */
5
6/*
7 * Copyright (C) 2016-2017 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/crypto/x509.h>
32
33#include <iprt/err.h>
34#include <iprt/string.h>
35#include <iprt/test.h>
36
37#include "tstRTCrX509-1.h"
38
39
40/*********************************************************************************************************************************
41* Global Variables *
42*********************************************************************************************************************************/
43static RTTEST g_hTest;
44
45/** List of test certificates + keys, PEM encoding, and their corresponding
46 * .der certificate encodings. */
47static const struct
48{
49 const char *pszFile;
50 bool fMaybeNotInOpenSSL;
51 bool fSelfSigned;
52 int rcSuccessDigestQuality;
53
54 char const *pchPem;
55 size_t cbPem;
56
57 uint8_t const *pbDer;
58 size_t cbDer;
59} g_aFiles[] =
60{
61#define MY_CERT_ENTRY(a_fMaybeNotInOpenSSL, a_fSelfSigned, a_rcSuccessDigestQuality, a_Name) \
62 { #a_Name, a_fMaybeNotInOpenSSL, a_fSelfSigned, a_rcSuccessDigestQuality, \
63 (const char *)RT_CONCAT(g_abPem_, a_Name), RT_CONCAT(g_cbPem_, a_Name), \
64 RT_CONCAT(g_abDer_, a_Name), RT_CONCAT(g_cbDer_, a_Name) }
65 MY_CERT_ENTRY(true, true, VINF_CR_DIGEST_SEVERELY_COMPROMISED, md4),
66 MY_CERT_ENTRY(false, true, VINF_CR_DIGEST_COMPROMISED, md5),
67 MY_CERT_ENTRY(false, true, VINF_CR_DIGEST_DEPRECATED, sha1),
68 MY_CERT_ENTRY(false, true, VINF_SUCCESS, sha224),
69 MY_CERT_ENTRY(false, true, VINF_SUCCESS, sha256),
70 MY_CERT_ENTRY(false, true, VINF_SUCCESS, sha384),
71 MY_CERT_ENTRY(false, true, VINF_SUCCESS, sha512),
72 MY_CERT_ENTRY(false, false, -1, cert1),
73};
74
75
76static void test1()
77{
78 RTTestSub(g_hTest, "Basics");
79 int rc;
80 for (unsigned i = 0; i < RT_ELEMENTS(g_aFiles); i++)
81 {
82 /*
83 * Decode.
84 */
85 /* Raw decoding of DER bytes, structure will have pointers to the raw data. */
86 RTCRX509CERTIFICATE Cert0;
87 RTASN1CURSORPRIMARY PrimaryCursor;
88 RTAsn1CursorInitPrimary(&PrimaryCursor, g_aFiles[i].pbDer, (uint32_t)g_aFiles[i].cbDer,
89 NULL /*pErrInfo*/, &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, NULL /*pszErrorTag*/);
90 rc = RTCrX509Certificate_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Cert0, "Cert0");
91 if (RT_SUCCESS(rc))
92 {
93 rc = RTCrX509Certificate_CheckSanity(&Cert0, 0, NULL /*pErrInfo*/, "Cert0");
94 if (RT_SUCCESS(rc))
95 {
96 /* Check the API, this clones the certificate so no data pointers. */
97 RTCRX509CERTIFICATE Cert1;
98 memset(&Cert1, i, sizeof(Cert1));
99 rc = RTCrX509Certificate_ReadFromBuffer(&Cert1, g_aFiles[i].pbDer, g_aFiles[i].cbDer, 0 /*fFlags*/,
100 &g_RTAsn1EFenceAllocator, NULL /*pErrInfo*/, NULL /*pszErrorTag*/);
101 if (RT_SUCCESS(rc))
102 {
103 /* Read the PEM variant. */
104 RTCRX509CERTIFICATE Cert2;
105 memset(&Cert2, ~i, sizeof(Cert2));
106 rc = RTCrX509Certificate_ReadFromBuffer(&Cert2, g_aFiles[i].pchPem, g_aFiles[i].cbPem, 0 /*fFlags*/,
107 &g_RTAsn1DefaultAllocator, NULL /*pErrInfo*/, NULL /*pszErrorTag*/);
108 if (RT_SUCCESS(rc))
109 {
110 /*
111 * Compare them, they should be all the same.
112 */
113 if (RTCrX509Certificate_Compare(&Cert0, &Cert1) != 0)
114 RTTestIFailed("Cert0 and Cert1 (DER) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
115 else if (RTCrX509Certificate_Compare(&Cert0, &Cert2) != 0)
116 RTTestIFailed("Cert0 and Cert2 (PEM) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
117 else if (RTCrX509Certificate_Compare(&Cert1, &Cert2) != 0)
118 RTTestIFailed("Cert1 (DER) and Cert2 (PEM) decoding of file %s (#%u) differs", g_aFiles[i].pszFile, i);
119 else
120 {
121 /*
122 * Encode the certificates.
123 */
124 unsigned j;
125 PRTCRX509CERTIFICATE paCerts[] = { &Cert0, &Cert1, &Cert2 };
126 for (j = 0; j < RT_ELEMENTS(paCerts); j++)
127 {
128 uint32_t cbEncoded = ~(j ^ i);
129 RTTESTI_CHECK_RC(rc = RTAsn1EncodePrepare(&paCerts[j]->SeqCore.Asn1Core,
130 RTASN1ENCODE_F_DER, &cbEncoded, NULL), VINF_SUCCESS);
131 if (RT_SUCCESS(rc) && cbEncoded != g_aFiles[i].cbDer)
132 RTTestIFailed("RTAsn1EncodePrepare of file %s (#%u) returned %#x bytes instead of %#x",
133 g_aFiles[i].pszFile, i, cbEncoded, g_aFiles[i].cbDer);
134
135 cbEncoded = (uint32_t)g_aFiles[i].cbDer;
136 void *pvTmp = RTTestGuardedAllocTail(g_hTest, cbEncoded);
137 RTTESTI_CHECK_RC(rc = RTAsn1EncodeToBuffer(&paCerts[j]->SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
138 pvTmp, cbEncoded, NULL /*pErrInfo*/), VINF_SUCCESS);
139 if (RT_SUCCESS(rc) && memcmp(pvTmp, g_aFiles[i].pbDer, cbEncoded) != 0)
140 RTTestIFailed("RTAsn1EncodeToBuffer produces the wrong output for file %s (#%u), variation %u",
141 g_aFiles[i].pszFile, i, j);
142 RTTestGuardedFree(g_hTest, pvTmp);
143 }
144
145 /*
146 * Check that our self signed check works.
147 */
148 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert0) == g_aFiles[i].fSelfSigned);
149 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert1) == g_aFiles[i].fSelfSigned);
150 RTTESTI_CHECK(RTCrX509Certificate_IsSelfSigned(&Cert2) == g_aFiles[i].fSelfSigned);
151
152 if (g_aFiles[i].fSelfSigned)
153 {
154 /*
155 * Verify the certificate signature (self signed).
156 */
157 for (j = 0; j < RT_ELEMENTS(paCerts); j++)
158 {
159 rc = RTCrX509Certificate_VerifySignatureSelfSigned(paCerts[j], NULL /*pErrInfo*/);
160 if (RT_FAILURE(rc))
161 RTTestIFailed("RTCrX509Certificate_VerifySignatureSelfSigned failed for %s (#%u), variation %u: %Rrc",
162 g_aFiles[i].pszFile, i, j, rc);
163 else if ( rc != g_aFiles[i].rcSuccessDigestQuality
164 && g_aFiles[i].rcSuccessDigestQuality != -1)
165 RTTestIFailed("RTCrX509Certificate_VerifySignatureSelfSigned returned %Rrc rather than %Rrc for %s (#%u), variation %u",
166 rc, g_aFiles[i].rcSuccessDigestQuality, g_aFiles[i].pszFile, i, j);
167 }
168 }
169 }
170
171 RTCrX509Certificate_Delete(&Cert2);
172 }
173 else
174 RTTestIFailed("Error %Rrc decoding PEM file %s (#%u)", rc, g_aFiles[i].pszFile, i);
175 RTCrX509Certificate_Delete(&Cert1);
176 }
177 else
178 RTTestIFailed("Error %Rrc decoding DER file %s (#%u)", rc, g_aFiles[i].pszFile, i);
179 }
180 RTCrX509Certificate_Delete(&Cert0);
181 }
182 }
183}
184
185
186
187
188int main()
189{
190 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTCrX509-1", &g_hTest);
191 if (rcExit != RTEXITCODE_SUCCESS)
192 return rcExit;
193 RTTestBanner(g_hTest);
194
195 test1();
196
197
198 return RTTestSummaryAndDestroy(g_hTest);
199}
200
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