VirtualBox

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

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

iprt/asn1: Fixed bug represnation of explicit tags that caused trouble doing encoding by piggypacking on the enumeration method. Added simple X.509 testcase.

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