Ejemplo n.º 1
0
/* Encodes the string represented by value as the string type type into the
 * CERT_NAME_BLOB output.  If there is an error and ppszError is not NULL,
 * *ppszError is set to the first failing character.  If there is no error,
 * output's pbData must be freed with LocalFree.
 */
static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
 const struct X500TokenW *value, PCERT_NAME_BLOB output, DWORD type,
 LPCWSTR *ppszError)
{
    CERT_NAME_VALUE nameValue = { type, { 0, NULL } };
    BOOL ret = TRUE;

    if (value->end > value->start)
    {
        nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
         sizeof(WCHAR));
        if (!nameValue.Value.pbData)
        {
            SetLastError(ERROR_OUTOFMEMORY);
            ret = FALSE;
        }
    }
    if (ret)
    {
        if (value->end > value->start)
        {
            DWORD i;
            LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;

            for (i = 0; i < value->end - value->start; i++)
            {
                *ptr++ = value->start[i];
                if (value->start[i] == '"')
                    i++;
            }
            nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData;
        }
        ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE,
         &nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData,
         &output->cbData);
        if (!ret && ppszError)
        {
            if (type == CERT_RDN_NUMERIC_STRING &&
             GetLastError() == CRYPT_E_INVALID_NUMERIC_STRING)
                *ppszError = value->start + output->cbData;
            else if (type == CERT_RDN_PRINTABLE_STRING &&
             GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING)
                *ppszError = value->start + output->cbData;
            else if (type == CERT_RDN_IA5_STRING &&
             GetLastError() == CRYPT_E_INVALID_IA5_STRING)
                *ppszError = value->start + output->cbData;
        }
        CryptMemFree(nameValue.Value.pbData);
    }
    return ret;
}
Ejemplo n.º 2
0
BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
 DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
 LPCWSTR *ppszError)
{
    CERT_NAME_INFO info = { 0, NULL };
    LPCWSTR str;
    struct KeynameKeeper keeper;
    DWORD i, error = ERROR_SUCCESS;
    BOOL ret = TRUE;

    TRACE("(%08lx, %s, %08lx, %p, %p, %p, %p)\n", dwCertEncodingType,
     debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded,
     ppszError);

    CRYPT_InitializeKeynameKeeper(&keeper);
    str = pszX500;
    while (str && *str && !error && ret)
    {
        struct X500TokenW token;

        error = CRYPT_GetNextKeyW(str, &token, ppszError);
        if (!error && token.start)
        {
            PCCRYPT_OID_INFO keyOID;

            CRYPT_KeynameKeeperFromTokenW(&keeper, &token);
            keyOID = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, keeper.keyName,
             CRYPT_RDN_ATTR_OID_GROUP_ID);
            if (!keyOID)
            {
                if (ppszError)
                    *ppszError = token.start;
                error = CRYPT_E_INVALID_X500_STRING;
            }
            else
            {
                str = token.end;
                while (isspace(*str))
                    str++;
                if (*str != '=')
                {
                    if (ppszError)
                        *ppszError = str;
                    error = CRYPT_E_INVALID_X500_STRING;
                }
                else
                {
                    static const WCHAR commaSep[] = { ',',0 };
                    static const WCHAR semiSep[] = { ';',0 };
                    static const WCHAR crlfSep[] = { '\r','\n',0 };
                    static const WCHAR allSeps[] = { ',',';','\r','\n',0 };
                    LPCWSTR sep;

                    str++;
                    if (dwStrType & CERT_NAME_STR_COMMA_FLAG)
                        sep = commaSep;
                    else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
                        sep = semiSep;
                    else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
                        sep = crlfSep;
                    else
                        sep = allSeps;
                    error = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
                     ppszError);
                    if (!error)
                    {
                        str = token.end;
                        ret = CRYPT_ValueToRDN(dwCertEncodingType, &info,
                         keyOID, &token, ppszError);
                    }
                }
            }
        }
    }
    CRYPT_FreeKeynameKeeper(&keeper);
    if (!error)
    {
        ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info,
         0, NULL, pbEncoded, pcbEncoded);
        for (i = 0; i < info.cRDN; i++)
        {
            DWORD j;

            for (j = 0; j < info.rgRDN[i].cRDNAttr; j++)
                LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData);
            CryptMemFree(info.rgRDN[i].rgRDNAttr);
        }
        CryptMemFree(info.rgRDN);
    }
    else
    {
        SetLastError(error);
        ret = FALSE;
    }
    return ret;
}
Ejemplo n.º 3
0
/**
 *
 * save public or private key to PEM format
 *
 * ofile   : name of file to write PEM encoded key
 * pemType : type of key being saved
 * rsa     : RSA object with public and private keys
 *
 */
int rsa_write_key(RSA* rsa,
                  const char* ofile, int pemType)
{
    DWORD  pkiLen, derLen;
    LPVOID pki, derData;
    BOOL   ok = FALSE;

    // public key?
    if (pemType == RSA_PUBLIC_KEY) {
        // get size of public key info
        if (CryptExportPublicKeyInfo(rsa->prov, AT_KEYEXCHANGE,
                                     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                     NULL, &pkiLen)) {
            // allocate memory
            pki = xmalloc(pkiLen);

            // export public key info
            if (CryptExportPublicKeyInfo(rsa->prov, AT_KEYEXCHANGE,
                                         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                         pki, &pkiLen)) {
                // get size of DER encoding
                if (CryptEncodeObjectEx(
                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                        X509_PUBLIC_KEY_INFO, pki, 0,
                        NULL, NULL, &derLen)) {
                    derData = xmalloc(derLen);
                    // convert to DER format
                    ok = CryptEncodeObjectEx(
                             X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                             X509_PUBLIC_KEY_INFO, pki, 0,
                             NULL, derData, &derLen);

                    // write to PEM file
                    if (ok) {
                        rsa_write_pem(RSA_PUBLIC_KEY, derData, derLen, ofile);
                        xfree(derData);
                    }
                }
            }
        }
    } else {
        // get length of PKCS#8 encoding
        if (CryptExportPKCS8(rsa->prov, AT_KEYEXCHANGE,
                             szOID_RSA_RSA, 0, NULL, NULL, &pkiLen)) {
            pki = xmalloc(pkiLen);

            if (pki != NULL) {
                // export the private key
                ok = CryptExportPKCS8(rsa->prov, AT_KEYEXCHANGE,
                                      szOID_RSA_RSA, 0x8000, NULL,
                                      pki, &pkiLen);

                // write key to PEM file
                if (ok) {
                    rsa_write_pem(RSA_PRIVATE_KEY, pki, pkiLen, ofile);
                }

                xfree(pki);
            }
        }
    }

    return ok;
}
Ejemplo n.º 4
0
	inline 	
	std::vector<unsigned char> create_req_blob(stcrypt::cert_name_t const& name, NCRYPT_KEY_HANDLE const subject_public_key, boost::optional<stcrypt::cert_name_t const&> const& issuer = boost::none){

		auto const& subject_name_2 = name.x500_string();
		auto const subject_name = subject_name_2.c_str();

		wchar_t const*const dummy_issuer_name = L"";

		boost::uuids::uuid const serial_and_unique_id( (boost::uuids::random_generator()()) );

		std::vector<BYTE> serial_blob_data;
		serial_blob_data.reserve( serial_and_unique_id.static_size() );
		std::copy(serial_and_unique_id.begin(), serial_and_unique_id.end(), std::back_inserter(serial_blob_data) );


 		CERT_INFO	cert_info={0};
 
 		cert_info.dwVersion = CERT_V3;
 
		cert_info.SerialNumber.pbData = serial_blob_data.data();
		cert_info.SerialNumber.cbData = serial_blob_data.size();

		cert_info.SubjectUniqueId.pbData = serial_blob_data.data();
		cert_info.SubjectUniqueId.cbData = serial_blob_data.size();

		CRYPT_ALGORITHM_IDENTIFIER signature_alg={OID_G34311_DSTU4145_SIGN,0};

		cert_info.SignatureAlgorithm = signature_alg;

 		SYSTEMTIME cs;
 		GetSystemTime(&cs);
 		{auto const r = SystemTimeToFileTime(&cs, &cert_info.NotBefore); assert(r);}
 		cs.wYear += 1; 
 		{auto const r = SystemTimeToFileTime(&cs, &cert_info.NotAfter); assert(r);}

		std::vector<unsigned char> subject_name_blob_data;
		std::vector<unsigned char> issuer_name_blob_data;

		ms_cert::cert_str_to_name_blob(subject_name, cert_info.Subject, subject_name_blob_data);

		if(issuer){
			auto const& issuer_x500_string = issuer->x500_string();
			ms_cert::cert_str_to_name_blob(issuer_x500_string.c_str(), cert_info.Issuer, issuer_name_blob_data);
		} else {
			ms_cert::cert_str_to_name_blob(dummy_issuer_name, cert_info.Issuer, issuer_name_blob_data);
		}
 
  		DWORD pub_key_size;
  		if( !CryptExportPublicKeyInfoEx(subject_public_key, 0, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, OID_DSTU4145_PUBKEY, 0, 0, 0, &pub_key_size) ){
  			STCRYPT_UNEXPECTED();
 		}
		STCRYPT_CHECK(pub_key_size!=0);
		
		std::vector<unsigned char> subject_pub_key_info_data(pub_key_size);
		if( !CryptExportPublicKeyInfoEx(subject_public_key, 0, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, OID_DSTU4145_PUBKEY, 0, 0,  static_cast<CERT_PUBLIC_KEY_INFO*>( static_cast<void*>(subject_pub_key_info_data.data())), &pub_key_size) ){
			STCRYPT_UNEXPECTED();
		}
		subject_pub_key_info_data.resize(pub_key_size);

		CERT_PUBLIC_KEY_INFO * subject_pub_key_info = static_cast<CERT_PUBLIC_KEY_INFO*>( static_cast<void*>( subject_pub_key_info_data.data() ) );
		cert_info.SubjectPublicKeyInfo = *subject_pub_key_info;

		DWORD cert_encoded_size = 0;
		STCRYPT_CHECK( CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &cert_info, 0, 0, 0, &cert_encoded_size)!=0 );
		STCRYPT_CHECK( cert_encoded_size!=0 );

		std::vector<unsigned char> cert_to_be_signed_blob(cert_encoded_size);
		STCRYPT_CHECK( CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &cert_info, 0, 0, cert_to_be_signed_blob.data(), &cert_encoded_size)!=0 );
		cert_to_be_signed_blob.resize( cert_encoded_size );

		return cert_to_be_signed_blob;
	}