p7cinfo.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:8k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  * 
  13.  * The Original Code is the Netscape security libraries.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are 
  17.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  18.  * Rights Reserved.
  19.  * 
  20.  * Contributor(s):
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34. #include "p7cinfo.h"
  35. #include "ssmerrs.h"
  36. /* Shorthand macros for inherited classes */
  37. #define SSMRESOURCE(ci) (&(ci)->super)
  38. SSMStatus
  39. SSMP7ContentInfo_Create(void *arg, SSMControlConnection * connection, 
  40.                         SSMResource **res)
  41. {
  42.     SSMStatus rv = PR_SUCCESS;
  43.     SSMP7ContentInfo *ci;
  44.     *res = NULL; /* in case we fail */
  45.     
  46.     ci = (SSMP7ContentInfo *) PR_CALLOC(sizeof(SSMP7ContentInfo));
  47.     if (!ci) goto loser;
  48.     
  49.     SSMRESOURCE(ci)->m_connection = connection;
  50.     rv = SSMP7ContentInfo_Init(ci, connection, (SEC_PKCS7ContentInfo *) arg, 
  51.        SSM_RESTYPE_PKCS7_CONTENT_INFO);
  52.     if (rv != PR_SUCCESS) goto loser;
  53.     SSMP7ContentInfo_Invariant(ci);
  54.     *res = SSMRESOURCE(ci);
  55.     return PR_SUCCESS;
  56.  loser:
  57.     if (rv == PR_SUCCESS) rv = PR_FAILURE;
  58.     if (ci) 
  59.     {
  60.         SSMRESOURCE(ci)->m_refCount = 1; /* force destroy */
  61.         SSM_FreeResource(SSMRESOURCE(ci));
  62.     }
  63.         
  64.     return rv;
  65. }
  66. SSMStatus 
  67. SSMP7ContentInfo_Init(SSMP7ContentInfo *ci, SSMControlConnection * conn, 
  68.   SEC_PKCS7ContentInfo *cinfo,
  69.   SSMResourceType type)
  70. {
  71.     SSMStatus rv = PR_SUCCESS;
  72.     /* Initialize superclass */
  73.     rv = SSMResource_Init(conn, SSMRESOURCE(ci), type);
  74. if (rv != PR_SUCCESS) goto loser;
  75. /* Fill in the content info */
  76. PR_ASSERT(cinfo != NULL);
  77. ci->m_cinfo = cinfo;
  78.     /* Sanity check before returning */
  79.     SSMP7ContentInfo_Invariant(ci);
  80.     
  81.     goto done;
  82.  loser:
  83.     /* member destruct, if any are allocated, will happen in the
  84.        _Destroy method */
  85.     if (rv == PR_SUCCESS) rv = PR_FAILURE;
  86.  done:
  87.     return rv;
  88. }
  89. SSMStatus 
  90. SSMP7ContentInfo_Destroy(SSMResource *res, PRBool doFree)
  91. {
  92.     SSMP7ContentInfo *ci = (SSMP7ContentInfo *) res;
  93.     SSMP7ContentInfo_Invariant(ci);
  94.     /* Destroy our members. */
  95.     if (ci->m_cinfo)
  96.     {
  97.         SEC_PKCS7DestroyContentInfo(ci->m_cinfo);
  98.         ci->m_cinfo = NULL;
  99.     }
  100.     /* Destroy superclass. */
  101.     SSMResource_Destroy(res, PR_FALSE);
  102.     
  103.     /* Free if asked. */
  104.     if (doFree)
  105.         PR_Free(res);
  106.     return PR_SUCCESS;
  107. }
  108. void 
  109. SSMP7ContentInfo_Invariant(SSMP7ContentInfo *ci)
  110. {
  111.     /* Superclass invariant */
  112.     SSMResource_Invariant(SSMRESOURCE(ci));
  113.     
  114.     SSM_LockResource(SSMRESOURCE(ci));
  115.     /* Class check */
  116.     PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(ci), SSM_RESTYPE_PKCS7_CONTENT_INFO));
  117.     /* Member check */
  118. PR_ASSERT(ci->m_cinfo != NULL);
  119.     if (ci->m_signerCert)
  120.         PR_ASSERT(SSM_IsAKindOf(&(ci->m_signerCert->super),SSM_RESTYPE_CERTIFICATE));
  121.     SSM_UnlockResource(SSMRESOURCE(ci));
  122. }
  123. SSMStatus 
  124. SSMP7ContentInfo_GetAttrIDs(SSMResource *res,
  125.                               SSMAttributeID **ids,
  126.                               PRIntn *count)
  127. {
  128.     SSMStatus rv;
  129.     rv = SSMResource_GetAttrIDs(res, ids, count);
  130.     if (rv != PR_SUCCESS)
  131.         goto loser;
  132.     *ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 3) * sizeof(SSMAttributeID));
  133.     if (! *ids) goto loser;
  134.     (*ids)[*count++] = SSM_FID_P7CINFO_IS_SIGNED;
  135.     (*ids)[*count++] = SSM_FID_P7CINFO_IS_ENCRYPTED;
  136.     (*ids)[*count++] = SSM_FID_P7CINFO_SIGNER_CERT;
  137.     goto done;
  138.  loser:
  139.     if (rv == PR_SUCCESS) rv = PR_FAILURE;
  140.  done:
  141.     return rv;
  142. }
  143. SSMStatus 
  144. SSMP7ContentInfo_GetAttr(SSMResource *res,
  145.                          SSMAttributeID attrID, 
  146.                          SSMResourceAttrType attrType,
  147.                          SSMAttributeValue *value)
  148. {
  149.     SSMP7ContentInfo *cinfo = (SSMP7ContentInfo *) res;
  150.     SEC_PKCS7ContentInfo *info;
  151.     SSMStatus rv = SSM_SUCCESS;
  152.     SSMP7ContentInfo_Invariant(cinfo);
  153.     if (!cinfo)
  154.     {
  155.         rv = PR_INVALID_ARGUMENT_ERROR;
  156.         goto loser;
  157.     }
  158.     SSM_LockResource(SSMRESOURCE(cinfo));
  159.     info = cinfo->m_cinfo;
  160.     if (!info) 
  161.     {
  162.         rv = SSM_ERR_ATTRIBUTE_MISSING;
  163.         goto loser;
  164.     }
  165.     /* see what it is */
  166.     switch(attrID)
  167.     {
  168.     case SSM_FID_P7CINFO_IS_SIGNED:
  169.         value->type = SSM_NUMERIC_ATTRIBUTE;
  170.         value->u.numeric = SEC_PKCS7ContentIsSigned(cinfo->m_cinfo);
  171.         rv = SSM_SUCCESS;
  172.         break;
  173.     case SSM_FID_P7CINFO_IS_ENCRYPTED:
  174.         value->type = SSM_NUMERIC_ATTRIBUTE;
  175.         value->u.numeric = SEC_PKCS7ContentIsEncrypted(cinfo->m_cinfo);
  176.         rv = SSM_SUCCESS;
  177.         break;
  178.     case SSM_FID_P7CINFO_SIGNER_CERT:
  179.         /* Make sure we have a cert to return. */
  180.         rv = SSM_ERR_ATTRIBUTE_MISSING; /* by default */
  181.         /* want signed data */
  182.         if ((info->content.signedData) && 
  183.             /* want signer info */
  184.             (info->content.signedData->signerInfos) && 
  185.             /* 1 and only 1 signer 
  186.                ### mwelch what if we have more than one? */
  187.             (info->content.signedData->signerInfos[0]) && 
  188.             (info->content.signedData->signerInfos[1] == NULL))
  189.         {
  190.             /* Get the cert, wrap it in a resource, and return its ID. */
  191.             CERTCertificate *cert =
  192.                 info->content.signedData->signerInfos[0]->cert;
  193.             SSMResourceID certID;
  194.             if (!cert) goto loser; /* we could still have a null cert */
  195.             rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE,
  196.                                     cert, 
  197.                                     SSMRESOURCE(cinfo)->m_connection,
  198.                                     &certID,
  199.                                     (SSMResource **) &cinfo->m_signerCert);
  200.             SSMP7ContentInfo_Invariant(cinfo);
  201.             value->type = SSM_RID_ATTRIBUTE;
  202.             rv = SSM_ClientGetResourceReference(&cinfo->m_signerCert->super,
  203.                                                 &certID);
  204.             if (rv != PR_SUCCESS)
  205.                 goto loser;
  206.             rv = SSM_SUCCESS;
  207.          value->type = SSM_RID_ATTRIBUTE;
  208.         value->u.numeric = certID;
  209.             SSM_FreeResource(&cinfo->m_signerCert->super);
  210.         }
  211.         
  212.         break;
  213.     default:
  214.         rv = SSMResource_GetAttr(res,attrID,attrType,value);
  215.         if (rv != PR_SUCCESS) goto loser;
  216.     }
  217.     goto done;
  218.  loser:
  219.     value->type = SSM_NO_ATTRIBUTE;
  220.     if (rv == PR_SUCCESS)
  221.         rv = PR_FAILURE;
  222.  done:
  223.     if (cinfo)
  224.         SSM_UnlockResource(SSMRESOURCE(cinfo));
  225.     return rv;
  226. }
  227. SSMStatus SSMP7ContentInfo_VerifyDetachedSignature(SSMP7ContentInfo *ci,
  228.                                                    SECCertUsage usage,
  229.                                                    HASH_HashType hash,
  230.                                                    PRBool keepCerts,
  231.                                                    PRIntn digestLen,
  232.                                                    char *detachedDigest)
  233. {
  234. SSMStatus rv = PR_FAILURE;
  235. SECItem digest;
  236. SSMP7ContentInfo_Invariant(ci);
  237. digest.len = digestLen;
  238. digest.data = (unsigned char*) detachedDigest;
  239. if (ci->m_cinfo)
  240. {
  241. if (SEC_PKCS7VerifyDetachedSignature(ci->m_cinfo, usage,
  242.  &digest, hash, keepCerts))
  243. rv = SSM_SUCCESS;
  244. }
  245. return rv;
  246. }