--- /dev/null
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_PEM_INT_H
+# define HEADER_PEM_INT_H
+
+# include <openssl/pem.h>
+
+/* Found in crypto/pem/pvkfmt.c */
+int ossl_do_blob_header(const unsigned char **in, unsigned int length,
+ unsigned int *pmagic, unsigned int *pbitlen,
+ int *pisdss, int *pispub);
+int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
+ int skip_magic,
+ unsigned int *psaltlen, unsigned int *pkeylen);
+
+#endif
#include "internal/cryptlib.h"
#include <openssl/pem.h>
+#include "internal/pem_int.h"
#include <openssl/rand.h>
#include <openssl/bn.h>
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
static EVP_PKEY *b2i_dss(const unsigned char **in,
unsigned int bitlen, int ispub);
-static int do_blob_header(const unsigned char **in, unsigned int length,
- unsigned int *pmagic, unsigned int *pbitlen,
- int *pisdss, int *pispub)
+int ossl_do_blob_header(const unsigned char **in, unsigned int length,
+ unsigned int *pmagic, unsigned int *pbitlen,
+ int *pisdss, int *pispub)
{
const unsigned char *p = *in;
if (length < 16)
/* bType */
if (*p == MS_PUBLICKEYBLOB) {
if (*pispub == 0) {
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
return 0;
}
*pispub = 1;
} else if (*p == MS_PRIVATEKEYBLOB) {
if (*pispub == 1) {
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
return 0;
}
*pispub = 0;
p++;
/* Version */
if (*p++ != 0x2) {
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
return 0;
}
/* Ignore reserved, aiKeyAlg */
/* fall thru */
case MS_RSA1MAGIC:
if (*pispub == 0) {
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
return 0;
}
break;
/* fall thru */
case MS_RSA2MAGIC:
if (*pispub == 1) {
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
return 0;
}
break;
default:
- PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+ PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
return -1;
}
*in = p;
const unsigned char *p = *in;
unsigned int bitlen, magic;
int isdss;
- if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
+ if (ossl_do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
return NULL;
}
return NULL;
}
p = hdr_buf;
- if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+ if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
return NULL;
length = blob_length(bitlen, isdss, ispub);
# ifndef OPENSSL_NO_RC4
-static int do_PVK_header(const unsigned char **in, unsigned int length,
- int skip_magic,
- unsigned int *psaltlen, unsigned int *pkeylen)
+int ossl_do_PVK_header(const unsigned char **in, unsigned int length,
+ int skip_magic,
+ unsigned int *psaltlen, unsigned int *pkeylen)
{
const unsigned char *p = *in;
unsigned int pvk_magic, is_encrypted;
if (skip_magic) {
if (length < 20) {
- PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+ PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
return 0;
}
} else {
if (length < 24) {
- PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+ PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
return 0;
}
pvk_magic = read_ledword(&p);
if (pvk_magic != MS_PVKMAGIC) {
- PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+ PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
return 0;
}
}
return 0;
if (is_encrypted && *psaltlen == 0) {
- PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+ PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
return 0;
}
}
p = pvk_hdr;
- if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+ if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen))
return 0;
buflen = (int)keylen + saltlen;
buf = OPENSSL_malloc(buflen);
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
+#include "internal/pem_int.h"
#include <openssl/pkcs12.h> /* For the PKCS8 stuff o.O */
#include <openssl/rsa.h> /* For d2i_RSAPrivateKey */
#include <openssl/safestack.h>
return 1;
}
+static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount)
+{
+#ifdef OPENSSL_NO_DSA
+ return NULL;
+#else
+ OSSL_STORE_INFO *result = NULL;
+ int ispub = -1;
+
+ {
+ unsigned int magic = 0, bitlen = 0;
+ int isdss = 0;
+ unsigned char peekbuf[16] = { 0, };
+ const unsigned char *p = peekbuf;
+
+ if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0)
+ return 0;
+ if (!ossl_do_blob_header(&p, sizeof(peekbuf), &magic, &bitlen,
+ &isdss, &ispub))
+ return 0;
+ }
+
+ (*matchcount)++;
+
+ {
+ EVP_PKEY *tmp = ispub
+ ? b2i_PublicKey_bio(bp)
+ : b2i_PrivateKey_bio(bp);
+
+ if (tmp == NULL
+ || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) {
+ EVP_PKEY_free(tmp);
+ return 0;
+ }
+ }
+
+ return result;
+#endif
+}
+
+static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
+ void *ui_data, const char *uri,
+ int *matchcount)
+{
+#if defined(OPENSSL_NO_DSA) || defined(OPENSSL_NO_RC4)
+ return NULL;
+#else
+ OSSL_STORE_INFO *result = NULL;
+
+ {
+ unsigned int saltlen = 0, keylen = 0;
+ unsigned char peekbuf[24] = { 0, };
+ const unsigned char *p = peekbuf;
+
+ if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0)
+ return 0;
+ if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &saltlen, &keylen))
+ return 0;
+ }
+
+ (*matchcount)++;
+
+ {
+ EVP_PKEY *tmp = NULL;
+ struct pem_pass_data pass_data;
+
+ if (!file_fill_pem_pass_data(&pass_data, "PVK pass phrase", uri,
+ ui_method, ui_data)
+ || (tmp = b2i_PVK_bio(bp, file_get_pem_pass, &pass_data)) == NULL
+ || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) {
+ EVP_PKEY_free(tmp);
+ return 0;
+ }
+ }
+
+ return result;
+#endif
+}
+
static int file_read_asn1(BIO *bp, unsigned char **data, long *len)
{
BUF_MEM *mem = NULL;
goto endloop;
}
} else {
+ if ((result = file_try_read_msblob(ctx->_.file.file,
+ &matchcount)) != NULL
+ || (result = file_try_read_PVK(ctx->_.file.file,
+ ui_method, ui_data, ctx->uri,
+ &matchcount)) != NULL)
+ goto endloop;
+
if (!file_read_asn1(ctx->_.file.file, &data, &len)) {
ctx->errcnt++;
goto endloop;