VirtualBox

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

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

IPRT: Better fix for missing md4 failure; adding information status codes for indicating deprecated and compromised digests when used.

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