blob: 70ccce31de5a25344f6994d2bd362fe980276374 [file] [log] [blame]
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file implements a process to fuzz the certificate
* parser for weave.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
#include "FuzzUtils.h"
#include "../tools/weave/weave-tool.h"
using namespace nl::Weave::Profiles::Security;
bool gOpenSSLSet = false;
//Assume the user compiled with clang > 6.0
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
static uint8_t inCert[MAX_CERT_SIZE];
static uint8_t outCert[MAX_CERT_SIZE];
CertFormat outputFormats[4] =
{
kCertFormat_X509_PEM,
kCertFormat_X509_DER,
kCertFormat_Weave_Base64,
kCertFormat_Weave_Raw
};
bool res = true;
WEAVE_ERROR err;
uint32_t inCertLen = 0;
CertFormat inCertFormat;
CertFormat outCertFormat;
uint32_t outCertLen = 0;
if (size > sizeof(inCert))
{
fprintf(stderr, "weave: Input certificate too big\n");
ExitNow();
}
memcpy(inCert, data, size);
inCertLen = size;
if (!gOpenSSLSet)
{
InitOpenSSL();
gOpenSSLSet = true;
}
inCertFormat = DetectCertFormat(inCert, inCertLen);
for (int i = 0; i < 4; i++)
{
outCertFormat = outputFormats[i];
if (inCertFormat == outCertFormat)
{
memcpy(outCert, inCert, inCertLen);
outCertLen = inCertLen;
}
else
{
if (inCertFormat == kCertFormat_X509_PEM)
{
if (!X509PEMToDER(inCert, inCertLen))
ExitNow(res = false);
inCertFormat = kCertFormat_X509_DER;
}
else if (inCertFormat == kCertFormat_Weave_Base64)
{
if (!Base64Decode(inCert, inCertLen, inCert, sizeof(inCert), inCertLen))
ExitNow(res = false);
inCertFormat = kCertFormat_Weave_Raw;
}
if (inCertFormat == kCertFormat_X509_DER && (outCertFormat == kCertFormat_Weave_Raw || outCertFormat == kCertFormat_Weave_Base64))
{
err = ConvertX509CertToWeaveCert(inCert, inCertLen, outCert, sizeof(outCert), outCertLen);
if (err != WEAVE_NO_ERROR)
{
//fprintf(stderr, "weave: x509->Weave Error converting certificate: %s\n", nl::ErrorStr(err));
ExitNow(res = false);
}
}
else if (inCertFormat == kCertFormat_Weave_Raw && (outCertFormat == kCertFormat_X509_DER || outCertFormat == kCertFormat_X509_PEM))
{
err = ConvertWeaveCertToX509Cert(inCert, inCertLen, outCert, sizeof(outCert), outCertLen);
if (err != WEAVE_NO_ERROR)
{
//fprintf(stderr, "weave: Weave -> X509 Error converting certificate: %s\n", nl::ErrorStr(err));
ExitNow(res = false);
}
}
else
{
memcpy(outCert, inCert, inCertLen);
outCertLen = inCertLen;
}
if (outCertFormat == kCertFormat_X509_PEM)
{
if (!X509DERToPEM(outCert, outCertLen, sizeof(outCert)))
ExitNow(res = false);
}
else if (outCertFormat == kCertFormat_Weave_Base64)
{
if (!Base64Encode(outCert, outCertLen, outCert, sizeof(outCert), outCertLen))
ExitNow(res = false);
}
}
}
exit:
return res;
}
// When NOT building for fuzzing using libFuzzer, supply a main() function to satisfy
// the linker. Even though the resultant application does nothing, being able to link
// it confirms that the fuzzing tests can be built successfully.
#ifndef WEAVE_FUZZING_ENABLED
int main(int argc, char *argv[])
{
return 0;
}
#endif