VirtualBox

Changeset 104745 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
May 21, 2024 12:52:09 PM (8 months ago)
Author:
vboxsync
Message:

IPRT,Main: Reworked the newly introduced RTCrX509Certificate_Generate function. It's now called RTCrX509Certificate_GenerateSelfSignedRsa and takes a few more parameters. We still can't read the output it creates. Added a create-self-signed-rsa-cert command to RTSignTool for easy testing. bugref:10310

Location:
trunk/src/VBox/Runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/crypto/iprt-openssl.cpp

    r98103 r104745  
    4343#ifdef IPRT_WITH_OPENSSL    /* Whole file. */
    4444# include <iprt/err.h>
     45# include <iprt/file.h>
    4546# include <iprt/string.h>
    4647# include <iprt/mem.h>
     
    169170}
    170171
     172
    171173DECLHIDDEN(int) rtCrOpenSslConvertPkcs7Attribute(void **ppvOsslAttrib, PCRTCRPKCS7ATTRIBUTE pAttrib, PRTERRINFO pErrInfo)
    172174{
    173     const unsigned char *pabEncoded;
    174     uint32_t             cbEncoded;
    175     void                *pvFree;
     175    const unsigned char *pabEncoded = NULL;
     176    uint32_t             cbEncoded  = 0;
     177    void                *pvFree     = NULL;
    176178    int rc = RTAsn1EncodeQueryRawBits(RTCrPkcs7Attribute_GetAsn1Core(pAttrib),
    177179                                      (const uint8_t **)&pabEncoded, &cbEncoded, &pvFree, pErrInfo);
     
    199201
    200202
     203/**
     204 * Writes the content of the @a pvMemBio to the new file @a pszFilename.
     205 *
     206 * @returns IPRT status code.
     207 * @param   pvMemBio    The memory BIO to write out.
     208 * @param   pszFilename The destination file.  This will be created.
     209 *                      The function will fail if this already exists.
     210 * @param   pErrInfo    Where to provide additional error details. Optional.
     211 */
     212DECLHIDDEN(int) rtCrOpenSslWriteMemBioToNewFile(void *pvMemBio, const char *pszFilename, PRTERRINFO pErrInfo)
     213{
     214    int rc;
     215
     216    /* Get the BIO buffer pointer first. */
     217    BUF_MEM *pBioBuf = NULL;
     218    long rcOssl = BIO_get_mem_ptr((BIO *)pvMemBio, &pBioBuf);
     219    if (rcOssl > 0)
     220    {
     221        AssertPtr(pBioBuf);
     222        RTFILE hFile = NIL_RTFILE;
     223        rc = RTFileOpen(&hFile, pszFilename,
     224                        RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE | (0600 << RTFILE_O_CREATE_MODE_SHIFT));
     225        if (RT_SUCCESS(rc))
     226        {
     227            rc = RTFileWrite(hFile, pBioBuf->data, pBioBuf->length, NULL);
     228            if (RT_SUCCESS(rc))
     229            {
     230                rc = RTFileClose(hFile);
     231                AssertRCStmt(rc, rc = RTErrInfoSetF(pErrInfo, rc, "RTFileClose failed on '%s'", pszFilename));
     232            }
     233            else
     234            {
     235                rc = RTErrInfoSetF(pErrInfo, rc, "RTFileWrite(,,%#zx,) failed on '%s'", pBioBuf->length, pszFilename);
     236                RTFileClose(hFile);
     237            }
     238            if (RT_FAILURE(rc))
     239                RTFileDelete(pszFilename);
     240        }
     241        else
     242            rc = RTErrInfoSetF(pErrInfo, rc, "RTFileOpen failed on '%s'", pszFilename);
     243    }
     244    else
     245        rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "BIO_get_mem_ptr");
     246    return rc;
     247}
     248
     249
    201250#endif /* IPRT_WITH_OPENSSL */
    202251
  • trunk/src/VBox/Runtime/common/crypto/x509-create-sign.cpp

    r104574 r104745  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Crypto - X.509, Certificate Creation and Signing.
     3 * IPRT - Crypto - X.509, Certificate Creation.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    3939*   Header Files                                                                                                                 *
    4040*********************************************************************************************************************************/
    41 
    42 # if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    43 #  include <io.h>
    44 # endif
    45 
    46 #include <iprt/file.h>
    4741#include "internal/iprt.h"
    4842#include <iprt/crypto/x509.h>
    4943
    50 # ifdef _MSC_VER
    51 #  define IPRT_COMPILER_VCC_WITH_C_INIT_TERM_SECTIONS
    52 #  include "internal/compiler-vcc.h"
    53 # endif
    54 
    55 # if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    56 #  include <fcntl.h>
    57 # endif
    58 #include <iprt/err.h>
    59 #include <iprt/string.h>
    60 
    6144#ifdef IPRT_WITH_OPENSSL
     45# include <iprt/err.h>
     46# include <iprt/file.h>
     47# include <iprt/rand.h>
     48
     49# include "internal/iprt-openssl.h"
     50# include "internal/openssl-pre.h"
    6251# include <openssl/evp.h>
    6352# include <openssl/pem.h>
    6453# include <openssl/x509.h>
    6554# include <openssl/bio.h>
    66 
    67 #if defined(RT_OS_OS2)
    68 # define _O_WRONLY   O_WRONLY
    69 #endif
    70 
    71 RTDECL(int) RTCrX509Certificate_Generate(const char *pszServerCertificate, const char *pszServerPrivateKey)
     55# include "internal/openssl-post.h"
     56
     57
     58
     59RTDECL(int) RTCrX509Certificate_GenerateSelfSignedRsa(RTDIGESTTYPE enmDigestType, uint32_t cBits, uint32_t cSecsValidFor,
     60                                                      uint32_t fKeyUsage, uint64_t fExtKeyUsage, void *pvSubjectTodo,
     61                                                      const char *pszCertFile, const char *pszPrivateKeyFile, PRTERRINFO pErrInfo)
    7262{
    73     int rc = VINF_SUCCESS;
     63    AssertReturn(cSecsValidFor <= (uint32_t)INT32_MAX, VERR_OUT_OF_RANGE); /* larger values are not portable (win) */
     64    AssertReturn(!fKeyUsage, VERR_NOT_IMPLEMENTED);
     65    AssertReturn(!fExtKeyUsage, VERR_NOT_IMPLEMENTED);
     66    AssertReturn(pvSubjectTodo == NULL, VERR_NOT_IMPLEMENTED);
     67
    7468    /*
    75      * Set up private key using rsa
     69     * Translate enmDigestType.
    7670     */
    77     EVP_PKEY * pkey;
    78 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) /* OpenSSL 3 needed */
    79     pkey = EVP_RSA_gen(2048);
    80 #else
    81     pkey = EVP_PKEY_new();
    82     RSA * rsa;
    83     rsa = RSA_generate_key(
    84         2048,   /* Number of bits for the key */
     71    const EVP_MD * const pEvpDigest = (const EVP_MD *)rtCrOpenSslConvertDigestType(enmDigestType, pErrInfo);
     72    AssertReturn(pEvpDigest, pErrInfo ? pErrInfo->rc : VERR_CR_DIGEST_NOT_SUPPORTED);
     73
     74    /*
     75     * Create a new RSA private key.
     76     */
     77# if OPENSSL_VERSION_NUMBER >= 0x30000000 /* RSA_generate_key is depreated in v3 */
     78    EVP_PKEY * const pPrivateKey = EVP_RSA_gen(cBits);
     79    if (!pPrivateKey)
     80        return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_GEN_FAILED_RSA, "EVP_RSA_gen(%u) failed", cBits);
     81# else
     82    RSA * const pRsaKey = RSA_generate_key(
     83        cBits,  /* Number of bits for the key */
    8584        RSA_F4, /* Exponent - RSA_F4 is defined as 0x10001L */
    8685        NULL,   /* Callback */
    8786        NULL    /* Callback argument */
    8887    );
    89     EVP_PKEY_assign_RSA(pkey, rsa);
    90 #endif
    91 
    92     if ( pkey == NULL )
    93         return VERR_CR_KEY_GEN_FAILED_RSA;
     88    if (!pRsaKey)
     89        return RTErrInfoSetF(pErrInfo, VERR_CR_KEY_GEN_FAILED_RSA, "RSA_generate_key(%u,RSA_F4,,) failed", cBits);
     90
     91    EVP_PKEY * const pPrivateKey = EVP_PKEY_new();
     92    if (pPrivateKey)
     93        EVP_PKEY_assign_RSA(pPrivateKey, pRsaKey); /* Takes ownership of pRsaKey. */
     94    else
     95    {
     96        RSA_free(pRsaKey);
     97        return RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new failed");
     98    }
     99# endif
    94100
    95101    /*
    96      * Set up certificate
     102     * Construct the certificate.
    97103     */
    98     X509* tempX509 = X509_new();
    99     if ( tempX509 == NULL )
    100         return VERR_CR_X509_GENERIC_ERROR;
    101     X509_set_version(tempX509,0); /** Set to X509 version 1 */
    102     ASN1_INTEGER_set(X509_get_serialNumber(tempX509), 1);
    103 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
    104     X509_gmtime_adj(X509_getm_notBefore(tempX509), 0);
    105     X509_gmtime_adj(X509_getm_notAfter(tempX509), 60*60*24*3650); /** 10 years time */
    106 #else
    107     X509_gmtime_adj(X509_get_notBefore(tempX509), 0);
    108     X509_gmtime_adj(X509_get_notAfter(tempX509), 60*60*24*3650); /** 10 years time */
    109 #endif
    110     X509_set_pubkey(tempX509,pkey);
    111 
    112     X509_NAME *x509_name = NULL;
    113     x509_name = X509_get_subject_name(tempX509);
    114 
    115     rc = X509_set_issuer_name(tempX509, x509_name);
    116     if ( RT_FAILURE(rc) )
    117         return rc;
    118 
    119     rc = X509_sign( tempX509, pkey, EVP_sha1());
    120     if ( RT_FAILURE(rc) )
    121         return rc;
    122 
    123     RTFILE hKeyFile;
    124     rc = RTFileOpen(&hKeyFile, pszServerPrivateKey, RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE | (0600 << RTFILE_O_CREATE_MODE_SHIFT) );
    125     if ( RT_FAILURE(rc) )
    126         return rc;
    127 # ifndef _MSC_VER
    128     int fd1 = (int)RTFileToNative(hKeyFile);
     104    int   rc = VINF_SUCCESS;
     105    X509 *pNewCert = X509_new();
     106    if (pNewCert)
     107    {
     108        int rcOssl;
     109
     110        /* Set to X509 version 1: */
     111# if 0
     112        if (fKeyUsage || fExtKeyUsage)
     113            rcOssl = X509_set_version(pNewCert, RTCRX509TBSCERTIFICATE_V3);
     114        else
     115# endif
     116            rcOssl = X509_set_version(pNewCert, RTCRX509TBSCERTIFICATE_V1);
     117        AssertStmt(rcOssl > 0, rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_set_version failed"));
     118
     119        /* Set the serial number to a random number in the 1 - 1G range: */
     120        rcOssl = ASN1_INTEGER_set(X509_get_serialNumber(pNewCert), RTRandU32Ex(1, UINT32_MAX / 4));
     121        AssertStmt(rcOssl > 0, rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_set_version failed"));
     122
     123        /* The certificate is valid from now and the specifice number of seconds forwards: */
     124# if OPENSSL_VERSION_NUMBER >= 0x30000000
     125        AssertStmt(X509_gmtime_adj(X509_getm_notBefore(pNewCert), 0),
     126                   rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_gmtime_adj/before failed"));
     127        AssertStmt(X509_gmtime_adj(X509_getm_notAfter(pNewCert), cSecsValidFor),
     128                   rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_gmtime_adj/after failed"));
    129129# else
    130     int fd1 = _open_osfhandle(RTFileToNative(hKeyFile), _O_WRONLY);
    131 # endif
    132     if ( fd1 < 0 )
    133         return VERR_FILE_IO_ERROR;
    134 
    135     BIO *fp1 = BIO_new_fd(fd1, BIO_NOCLOSE);
    136     rc = PEM_write_bio_PrivateKey( fp1, pkey, NULL, NULL, 0, NULL, NULL);
    137     if ( RT_FAILURE(rc) )
    138         return rc;
    139     BIO_free(fp1);
    140 # ifdef _MSC_VER
    141     close(fd1);
    142 #endif
    143     RTFileClose(hKeyFile);
    144 
    145     RTFILE hCertFile;
    146     rc = RTFileOpen(&hCertFile, pszServerCertificate, RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE | (0600 << RTFILE_O_CREATE_MODE_SHIFT) );
    147     if ( RT_FAILURE(rc) )
    148         return rc;
    149 # ifndef _MSC_VER
    150     int fd2 = (int)RTFileToNative(hCertFile);
    151 # else
    152     int fd2 = _open_osfhandle(RTFileToNative(hCertFile), _O_WRONLY);
    153 # endif
    154     if ( fd2 < 0 )
    155         return VERR_FILE_IO_ERROR;
    156 
    157     BIO *fp2 = BIO_new_fd(fd2, BIO_NOCLOSE);
    158     rc = PEM_write_bio_X509( fp2, tempX509 );
    159     if ( RT_FAILURE(rc) )
    160         return rc;
    161     BIO_free(fp2);
    162 # ifdef _MSC_VER
    163     close(fd2);
    164 #endif
    165     RTFileClose(hCertFile);
    166 
    167     X509_free(tempX509);
    168     EVP_PKEY_free(pkey);
    169 
     130        AssertStmt(X509_gmtime_adj(X509_get_notBefore(pNewCert), 0),
     131                   rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_gmtime_adj/before failed"));
     132        AssertStmt(X509_gmtime_adj(X509_get_notAfter(pNewCert), cSecsValidFor),
     133                   rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_gmtime_adj/after failed"));
     134# endif
     135
     136        /* Set the public key (part of the private): */
     137        rcOssl = X509_set_pubkey(pNewCert, pPrivateKey);
     138        AssertStmt(rcOssl > 0, rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_set_pubkey failed"));
     139
     140# if 0
     141        /* Set key usage. */
     142        if (fKeyUsage)
     143        {
     144        }
     145        /* Set extended key usage. */
     146        if (fExtKeyUsage)
     147        {
     148        }
     149# endif
     150        /** @todo set other certificate attributes? */
     151
     152
     153        /** @todo check what the subject name is...  Offer way to specify it? */
     154
     155        /* Make it self signed: */
     156        X509_NAME *pX509Name = X509_get_subject_name(pNewCert);
     157        rcOssl = X509_set_issuer_name(pNewCert, pX509Name);
     158        AssertStmt(rcOssl > 0, rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "X509_set_issuer_name failed"));
     159
     160        if (RT_SUCCESS(rc))
     161        {
     162            /*
     163             * Sign the certificate.
     164             */
     165            rcOssl = X509_sign(pNewCert, pPrivateKey, pEvpDigest);
     166            if (rcOssl > 0)
     167            {
     168                /*
     169                 * Write out the result to the two files.
     170                 */
     171                /* The certificate (not security sensitive). */
     172                BIO * const pCertBio = BIO_new(BIO_s_mem());
     173                if (pCertBio)
     174                {
     175                    rcOssl = PEM_write_bio_X509(pCertBio, pNewCert);
     176                    if (rcOssl > 0)
     177                        rc = rtCrOpenSslWriteMemBioToNewFile(pCertBio, pszCertFile, pErrInfo);
     178                    else
     179                        rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_GEN_FAILED_RSA, "PEM_write_bio_X509 failed");
     180                    BIO_free(pCertBio);
     181                }
     182                else
     183                    rc = VERR_NO_MEMORY;
     184
     185                if (RT_SUCCESS(rc))
     186                {
     187                    /* The private key as plain text (security sensitive, thus last). */
     188                    BIO * const pPkBio = BIO_new(BIO_s_secmem());
     189                    if (pPkBio)
     190                    {
     191                        rcOssl = PEM_write_bio_PrivateKey(pPkBio, pPrivateKey,
     192                                                          NULL /*enc*/, NULL /*kstr*/, 0 /*klen*/, NULL /*cb*/, NULL /*u*/);
     193                        if (rcOssl > 0)
     194                            rc = rtCrOpenSslWriteMemBioToNewFile(pPkBio, pszPrivateKeyFile, pErrInfo);
     195                        else
     196                            rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_GEN_FAILED_RSA, "PEM_write_bio_PrivateKey failed");
     197                        BIO_free(pPkBio);
     198                    }
     199                    else
     200                        rc = VERR_NO_MEMORY;
     201                    if (RT_FAILURE(rc))
     202                        RTFileDelete(pszCertFile);
     203                }
     204            }
     205            else
     206                rc = RTErrInfoSet(pErrInfo, VERR_CR_KEY_GEN_FAILED_RSA, "X509_sign failed");
     207        }
     208
     209        X509_free(pNewCert);
     210    }
     211    else
     212        rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "X509_new failed");
     213
     214    EVP_PKEY_free(pPrivateKey);
    170215    return rc;
    171216}
  • trunk/src/VBox/Runtime/include/internal/iprt-openssl.h

    r98103 r104745  
    5454DECLHIDDEN(int)  rtCrOpenSslAddX509CertToStack(void *pvOsslStack, PCRTCRX509CERTIFICATE pCert, PRTERRINFO pErrInfo);
    5555DECLHIDDEN(const void /*EVP_MD*/ *) rtCrOpenSslConvertDigestType(RTDIGESTTYPE enmDigestType, PRTERRINFO pErrInfo);
    56 DECLHIDDEN(int) rtCrOpenSslConvertPkcs7Attribute(void **ppvOsslAttrib, PCRTCRPKCS7ATTRIBUTE pAttrib, PRTERRINFO pErrInfo);
     56DECLHIDDEN(int)  rtCrOpenSslConvertPkcs7Attribute(void **ppvOsslAttrib, PCRTCRPKCS7ATTRIBUTE pAttrib, PRTERRINFO pErrInfo);
    5757DECLHIDDEN(void) rtCrOpenSslFreeConvertedPkcs7Attribute(void *pvOsslAttrib);
    5858
     
    6060DECLHIDDEN(int)  rtCrKeyToOpenSslKeyEx(RTCRKEY hKey, bool fNeedPublic, const char *pszAlgoObjId,
    6161                                       void /*EVP_PKEY*/ **ppEvpKey, const void /*EVP_MD*/ **ppEvpMdType, PRTERRINFO pErrInfo);
     62DECLHIDDEN(int)  rtCrOpenSslWriteMemBioToNewFile(void *pvMemBio, const char *pszFilename, PRTERRINFO pErrInfo);
    6263
    6364RT_C_DECLS_END
  • trunk/src/VBox/Runtime/tools/RTSignTool.cpp

    r101647 r104745  
    62326232
    62336233
     6234/*********************************************************************************************************************************
     6235*   The 'create-self-signed-rsa-cert' command.                                                                                   *
     6236*********************************************************************************************************************************/
     6237static RTEXITCODE HelpCreateSelfSignedRsaCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     6238{
     6239    RT_NOREF_PV(enmLevel);
     6240    RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT,
     6241                        "create-self-signed-rsa-cert [--verbose|--quiet] [--key-bits <count>] [--digest <hash>] [--out-cert=]<certificate-file.pem> [--out-pkey=]<private-key-file.pem>\n");
     6242    return RTEXITCODE_SUCCESS;
     6243}
     6244
     6245
     6246static RTDIGESTTYPE DigestTypeStringToValue(const char *pszType)
     6247{
     6248    for (int iType = RTDIGESTTYPE_INVALID + 1; iType < RTDIGESTTYPE_END; iType++)
     6249        if (iType != RTDIGESTTYPE_UNKNOWN)
     6250        {
     6251            const char * const pszName = RTCrDigestTypeToName((RTDIGESTTYPE)iType);
     6252            size_t             offType = 0;
     6253            size_t             offName = 0;
     6254            for (;;)
     6255            {
     6256                char chType = RT_C_TO_UPPER(pszType[offType]);
     6257                char chName = RT_C_TO_UPPER(pszName[offType]);
     6258                if (chType != chName)
     6259                {
     6260                    /* allow 'sha1' as well as 'sha-1' */
     6261                    if (chName != '-')
     6262                        break;
     6263                    chName = pszName[++offName];
     6264                    chName = RT_C_TO_UPPER(chName);
     6265                    if (chType != chName)
     6266                        break;
     6267                }
     6268                if (chType == '\0')
     6269                    return (RTDIGESTTYPE)iType;
     6270            }
     6271        }
     6272    return RTDIGESTTYPE_INVALID;
     6273}
     6274
     6275
     6276static RTEXITCODE HandleCreateSelfSignedRsaCert(int cArgs, char **papszArgs)
     6277{
     6278    /*
     6279     * Parse arguments.
     6280     */
     6281    static const RTGETOPTDEF s_aOptions[] =
     6282    {
     6283        { "--digest",           'd', RTGETOPT_REQ_STRING },
     6284        { "--bits",             'b', RTGETOPT_REQ_UINT32 },
     6285        { "--key-bits",         'b', RTGETOPT_REQ_UINT32 },
     6286        { "--days",             'D', RTGETOPT_REQ_UINT32 },
     6287        { "--days",             'D', RTGETOPT_REQ_UINT32 },
     6288        { "--out-cert",         'c', RTGETOPT_REQ_UINT32 },
     6289        { "--out-certificate",  'c', RTGETOPT_REQ_UINT32 },
     6290        { "--out-pkey",         'p', RTGETOPT_REQ_UINT32 },
     6291        { "--out-private-key",  'p', RTGETOPT_REQ_UINT32 },
     6292        { "--secs",             's', RTGETOPT_REQ_UINT32 },
     6293        { "--seconds",          's', RTGETOPT_REQ_UINT32 },
     6294    };
     6295
     6296    RTDIGESTTYPE    enmDigestType   = RTDIGESTTYPE_SHA384;
     6297    uint32_t        cKeyBits        = 4096;
     6298    uint32_t        cSecsValidFor   = 365 * RT_SEC_1DAY;
     6299    uint32_t        fKeyUsage       = 0;
     6300    uint32_t        fExtKeyUsage    = 0;
     6301    const char     *pszOutCert      = NULL;
     6302    const char     *pszOutPrivKey   = NULL;
     6303
     6304    RTGETOPTSTATE GetState;
     6305    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     6306    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     6307    RTGETOPTUNION ValueUnion;
     6308    int ch;
     6309    while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
     6310    {
     6311        switch (ch)
     6312        {
     6313            case 'b':
     6314                cKeyBits = ValueUnion.u32;
     6315                break;
     6316
     6317            case 'd':
     6318                enmDigestType = DigestTypeStringToValue(ValueUnion.psz);
     6319                if (enmDigestType == RTDIGESTTYPE_INVALID)
     6320                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unknown digest type: %s", ValueUnion.psz);
     6321                break;
     6322
     6323            case 'D':
     6324                cSecsValidFor = ValueUnion.u32 * RT_SEC_1DAY;
     6325                if (cSecsValidFor / RT_SEC_1DAY != ValueUnion.u32)
     6326                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "The --days option value is out of range: %u", ValueUnion.u32);
     6327                break;
     6328
     6329            case 'c':
     6330                if (pszOutCert)
     6331                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "The --out-cert option can only be used once.");
     6332                pszOutCert = ValueUnion.psz;
     6333                break;
     6334
     6335            case 'p':
     6336                if (pszOutPrivKey)
     6337                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "The --out-pkey option can only be used once.");
     6338                pszOutPrivKey = ValueUnion.psz;
     6339                break;
     6340
     6341            case 's':
     6342                cSecsValidFor = ValueUnion.u32;
     6343                break;
     6344
     6345            case VINF_GETOPT_NOT_OPTION:
     6346                if (!pszOutCert)
     6347                    pszOutCert = ValueUnion.psz;
     6348                else if (!pszOutPrivKey)
     6349                    pszOutPrivKey = ValueUnion.psz;
     6350                else
     6351                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many output files specified: %s", ValueUnion.psz);
     6352                break;
     6353
     6354            case 'V': return HandleVersion(cArgs, papszArgs);
     6355            case 'h': return HelpCreateSelfSignedRsaCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
     6356            default:  return RTGetOptPrintError(ch, &ValueUnion);
     6357        }
     6358    }
     6359    if (!pszOutCert)
     6360        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output certificate file name specified.");
     6361    if (!pszOutPrivKey)
     6362        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output private key file name specified.");
     6363
     6364    /*
     6365     * Do the work.
     6366     */
     6367    RTERRINFOSTATIC StaticErrInfo;
     6368    rc = RTCrX509Certificate_GenerateSelfSignedRsa(enmDigestType, cKeyBits, cSecsValidFor,
     6369                                                   fKeyUsage, fExtKeyUsage, NULL /*pvSubjectTodo*/,
     6370                                                   pszOutCert, pszOutPrivKey, RTErrInfoInitStatic(&StaticErrInfo));
     6371    if (RT_SUCCESS(rc))
     6372    {
     6373        /*
     6374         * Test load it.
     6375         */
     6376        RTCRX509CERTIFICATE Certificate;
     6377        rc = RTCrX509Certificate_ReadFromFile(&Certificate, pszOutCert, RTCRX509CERT_READ_F_PEM_ONLY,
     6378                                              &g_RTAsn1DefaultAllocator, RTErrInfoInitStatic(&StaticErrInfo));
     6379        if (RT_FAILURE(rc))
     6380            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error reading the new certificate from %s: %Rrc%#RTeim",
     6381                                  pszOutCert, rc, &StaticErrInfo.Core);
     6382        RTCrX509Certificate_Delete(&Certificate);
     6383        return RTEXITCODE_SUCCESS;
     6384    }
     6385
     6386    return RTMsgErrorExitFailure("RTCrX509Certificate_GenerateSelfSignedRsa(%d,%u,%u,%s,%s,) failed: %Rrc%#RTeim",
     6387                                 enmDigestType, cKeyBits, cSecsValidFor, pszOutCert, pszOutPrivKey, rc, &StaticErrInfo.Core);
     6388}
     6389
     6390
     6391
    62346392/*
    62356393 * The 'version' command.
     
    62976455    { "hash-exe",                       HandleHashExe,                      HelpHashExe },
    62986456    { "make-tainfo",                    HandleMakeTaInfo,                   HelpMakeTaInfo },
     6457#ifndef IPRT_IN_BUILD_TOOL
     6458    { "create-self-signed-rsa-cert",    HandleCreateSelfSignedRsaCert,      HelpCreateSelfSignedRsaCert },
     6459#endif
    62996460    { "help",                           HandleHelp,                         HelpHelp },
    63006461    { "--help",                         HandleHelp,                         NULL },
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette