+++ /dev/null
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
- * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
- * specific language governing rights and limitations under the License.
- */
-
-
-//
-// pkcs8.cpp - PKCS8 key wrap/unwrap support.
-//
-
-
-#include "pkcs8.h"
-#include "AppleCSPUtils.h"
-#include "AppleCSPKeys.h"
-#include <Security/keyTemplates.h>
-#include <security_asn1/SecNssCoder.h>
-#include <security_asn1/nssUtils.h>
-#include "AppleCSPSession.h"
-#include <Security/cssmapple.h>
-
-/*
- * Given a key in PKCS8 format, fill in the following
- * header fields:
- *
- * CSSM_KEYBLOB_FORMAT Format
- * CSSM_ALGORITHMS AlgorithmId
- * uint32 LogicalKeySizeInBits
- */
-void AppleCSPSession::pkcs8InferKeyHeader(
- CssmKey &key)
-{
- /*
- * Incoming key blob is a PrivateKeyInfo. Take it apart
- * to get its algorithm info, from which we infer other
- * fields.
- */
- NSS_PrivateKeyInfo privKeyInfo;
- SecNssCoder coder;
- CSSM_DATA &keyData = key.KeyData;
-
- memset(&privKeyInfo, 0, sizeof(privKeyInfo));
- if(coder.decodeItem(keyData, kSecAsn1PrivateKeyInfoTemplate,
- &privKeyInfo)) {
- errorLog0("pkcs8InferKeyHeader decode error\n");
- CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
- }
-
- CSSM_KEYHEADER &hdr = key.KeyHeader;
- if(!cssmOidToAlg(&privKeyInfo.algorithm.algorithm,
- &hdr.AlgorithmId)) {
- errorLog0("pkcs8InferKeyHeader unknown algorithm\n");
- CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
- }
-
- switch(hdr.AlgorithmId) {
- case CSSM_ALGID_RSA:
- case CSSM_ALGID_ECDSA:
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- case CSSM_ALGID_DSA:
- /*
- * Try openssl style first, though our default when
- * wrapping is FIPS186
- */
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- default:
- /* punt */
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
- break;
- }
-
- /*
- * Find someone who knows about this key and ask them the
- * key size. infoProvider() throws if no provider found.
- */
- CSSM_KEY_SIZE keySize;
- try {
- auto_ptr<CSPKeyInfoProvider> provider(infoProvider(key));
- provider->QueryKeySizeInBits(keySize);
- }
- catch(const CssmError &cerror) {
- /*
- * Special case: DSA private keys keys can be in two forms - FIPS186
- * (for legacy implementations) and PKCS8 (for openssl). We're wired to
- * *generate* FIPS186 blobs by default in pkcs8RawKeyFormat(), but to
- * decode openssl-generated DSA private keys in wrapped FIPS186 format
- * we have to try both.
- */
- if((cerror.error == CSSMERR_CSP_INVALID_KEY) &&
- (hdr.AlgorithmId == CSSM_ALGID_DSA)) {
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- try {
- auto_ptr<CSPKeyInfoProvider> provider(infoProvider(key));
- provider->QueryKeySizeInBits(keySize);
- }
- catch(...) {
- /* out of luck */
- throw;
- }
- }
- else {
- /* other error, give up */
- throw;
- }
- }
- catch(...) {
- /* other (non-CSSM) error, give up */
- throw;
- }
- hdr.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits;
-}
-
-/*
- * When doing a PKCS8 wrap operation on a reference key, this
- * is used to infer the blob type to obtain before the encryption.
- * App can override this with a
- * CSSM_ATTRIBUTE_{PRIVATE,PUBLIC,SESSION}_KEY_FORMAT
- * context attribute.
- */
-CSSM_KEYBLOB_FORMAT pkcs8RawKeyFormat(
- CSSM_ALGORITHMS keyAlg)
-{
- switch(keyAlg) {
- case CSSM_ALGID_RSA:
- case CSSM_ALGID_ECDSA:
- return CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- case CSSM_ALGID_DSA:
- return CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
- default:
- /* punt */
- return CSSM_KEYBLOB_RAW_FORMAT_NONE;
- }
-}
-
-/*
- * When doing a OPENSSL style wrap operation on a reference key, this
- * is used to infer the blob type to obtain before the encryption.
- * App can override this with a
- * CSSM_ATTRIBUTE_{PRIVATE,PUBLIC,SESSION}_KEY_FORMAT
- * context attribute.
- */
-CSSM_KEYBLOB_FORMAT opensslRawKeyFormat(
- CSSM_ALGORITHMS keyAlg)
-{
- switch(keyAlg) {
- case CSSM_ALGID_RSA:
- return CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- case CSSM_ALGID_DSA:
- return CSSM_KEYBLOB_RAW_FORMAT_OPENSSL;
- case CSSM_ALGID_ECDSA:
- return CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- default:
- /* punt */
- return CSSM_KEYBLOB_RAW_FORMAT_NONE;
- }
-}
-
-/*
- * Given a key in some kind of openssl format (just subsequent to decryption
- * during an unwrap), fill in the following header fields:
- *
- * CSSM_KEYBLOB_FORMAT Format
- * uint32 LogicalKeySizeInBits
- */
-void AppleCSPSession::opensslInferKeyHeader(
- CssmKey &key)
-{
- CSSM_KEYHEADER &hdr = key.KeyHeader;
- switch(hdr.AlgorithmId) {
- case CSSM_ALGID_RSA:
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
- break;
- case CSSM_ALGID_DSA:
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL;
- break;
- case CSSM_ALGID_ECDSA:
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
- break;
- default:
- /* punt */
- hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_NONE;
- return;
- }
-
- /* now figure out the key size by finding a provider for this key */
- CSSM_KEY_SIZE keySize;
- try {
- auto_ptr<CSPKeyInfoProvider> provider(infoProvider(key));
- provider->QueryKeySizeInBits(keySize);
- }
- catch(...) {
- /* no recovery possible */
- throw;
- }
- hdr.LogicalKeySizeInBits = keySize.LogicalKeySizeInBits;
- return;
-}
-