⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 writeenv.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "p7obj.h"
#include "idobj.h"
#include "derhelp.h"
#include "oidlist.h"

/* Set up the OpenSSL ASN.1 templates.
 */
ASN1_SEQUENCE (Asn1EncryptedInfo) =
{
  ASN1_SIMPLE (Asn1EncryptedInfo, contentType, Asn1ObjectId),
  ASN1_SIMPLE (Asn1EncryptedInfo, algId, Asn1Encoded),
  ASN1_IMP (Asn1EncryptedInfo, encryptedContent, Asn1EncryptedContent, 0)
} ASN1_SEQUENCE_END (Asn1EncryptedInfo);

IMPLEMENT_ASN1_FUNCTIONS (Asn1EncryptedInfo)

ASN1_SEQUENCE (Asn1EnvelopedData) =
{
  ASN1_SIMPLE (Asn1EnvelopedData, version, ASN1_INTEGER),
  ASN1_SET_OF (Asn1EnvelopedData, recipInfo, Asn1RecipientInfo),
  ASN1_SIMPLE (Asn1EnvelopedData, encryptedInfo, Asn1EncryptedInfo)
} ASN1_SEQUENCE_END (Asn1EnvelopedData);

IMPLEMENT_ASN1_FUNCTIONS (Asn1EnvelopedData)

ASN1_SEQUENCE (Asn1EnvelopedContent) =
{
  ASN1_SIMPLE (Asn1EnvelopedContent, contentType, Asn1ObjectId),
  ASN1_EXP (Asn1EnvelopedContent, envelopedData, Asn1EnvelopedData, 0)
} ASN1_SEQUENCE_END (Asn1EnvelopedContent);

IMPLEMENT_ASN1_FUNCTIONS (Asn1EnvelopedContent)

/* The identity object should contain an encoded ID. Build the
 * identity-based IssuerAndSerialNumber out of it.
 *
 *  IssuerAndSerialNumber ::= SEQUENCE {
 *    issuer Name,
 *    serialNumber CertificateSerialNumber }
 *
 *  CertificateSerialNumber  ::=  INTEGER
 *
 * The serialNumber is always 1 (02 01 01).
 * <p>The Name will contain one Attribute (OID: id-at-name), which is the
 * PrintableString of the Base64 encoded identity string.
 *
 *   Name ::= CHOICE {
 *    RDNSequence }
 *
 *   RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 *
 *   RelativeDistinguishedName ::=
 *     SET OF AttributeTypeAndValue
 *
 *   AttributeTypeAndValue ::= SEQUENCE {
 *     type     AttributeType,
 *     value    AttributeValue }
 *
 *   AttributeType ::= OBJECT IDENTIFIER
 *
 *   AttributeValue ::= ANY DEFINED BY AttributeType
 *
 * The IssuerAndSerialNumber in this context will then be fixed at
 *
 *   30 len                           SEQ: IssuerAndSerialNumber
 *     30 len                           SEQ OF RDN
 *        31 len                          SET OF Attribute
 *           30 len                         SEQ: Attribute
 *              06 03                         OID
 *                 55 04 29
 *              13 len                        value (ANY, PrintableString)
 *                 <Base64 of encoded ID>
 *     02 01                            INTEGER: serialNumber
 *        01
 *
 * This function will allocate the space necessary to hold the encoding
 * and return the new buffer and its length. It is the responsibility
 * of the caller to free that memory.
 * <p>This function assumes that the identity has been encoded and that
 * it exists in the encoding field of the VoltIdentityObject. The
 * routine will do no argument checking.
 *
 * @param libCtx The library ctx to use.
 * @param idObj The object containing the ID to build into issuer and
 * serial number.
 * @param base64 An object built to encode binary data to Base64.
 * @param issuerSerial The address where the function will deposit the
 * pointer to the newly allocated buffer.
 * @param issuerSerialLen The address where the function will deposit
 * the length of the encoding.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV VoltBuildIssuerSerialAlloc VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VtIdentityObject idObj,
   VtAlgorithmObject base64,
   unsigned char **issuerSerial,
   unsigned int *issuerSerialLen
));

/* Build the RecipientData struct. The caller passes the RecipientData,
 * which should contain an idRef and nothing else. This function builds
 * the rest of the info.
 * <p>The function does no argument checking, it is the responsibility
 * of the caller not to make mistakes.
 *
 * @param p7Obj Contains things the function needs, such as libCtx and
 * localCtx.
 * @param random A source of random bytes, if necessary.
 * @param base64 An object built to encode binary data to Base64.
 * @param symKeyData The key data to encrypt with the recipient's
 * public key.
 * @param symKeyDataLen The length, in bytes, of the key data.
 * @param recipientData The struct containing the identity and the
 * empty fields to fill.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV VoltBuildRecipientData VOLT_PROTO_LIST ((
   VoltPkcs7Object *p7Obj,
   VtRandomObject random,
   VtAlgorithmObject base64,
   unsigned char *symKeyData,
   unsigned int symKeyDataLen,
   VoltRecipientData *recipientData
));

int VoltP7EnvWriteInit (
   VtPkcs7Object pkcs7Obj,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtRandomObject random
   )
{
  int status;
  unsigned int index, indexC, indexD, idCount, maxIndex, keyLen;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VoltPkcs7WriteEnvCtx *envCtx = (VoltPkcs7WriteEnvCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  unsigned char *keyData = (unsigned char *)0;
  VtAlgorithmObject base64 = (VtAlgorithmObject)0;
  VtIdentityObject currentId, compareId;
  VtBase64Info base64Info;
  VtItem keyItem;
  VtItem *getKeyData;

  do
  {
    /* The state must be VOLT_P7_STATE_ENV_WRITE_SET, if not, we're
     * not allowed to call WriteInit.
     */
    status = VT_ERROR_INVALID_CALL_ORDER;
    if (obj->state != VOLT_P7_STATE_ENV_WRITE_SET)
      break;

    /* This implementation does not work without recipients or a
     * symmetric encryptor.
     */
    status = VT_ERROR_INVALID_P7_OBJ;
    if ( (envCtx->recipList == (VtIdentityList)0) ||
         (envCtx->symEncryptor == (VtAlgorithmObject)0) )
      break;

    /* Make sure the recipientData array is not yet built.
     */
    if (envCtx->recipients != (VoltRecipientData *)0)
      break;

    /* Build a Base64 object. We'll need it later for each recipient,
     * so rather than build again and again, build one now and pass it
     * around.
     */
    base64Info.base64BlockSize = 76;
    base64Info.newLineCharacter = VT_BASE64_NO_NEW_LINE;
    base64Info.errorCheck = VT_BASE64_NO_ERROR_CHECK;
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplBase64, (Pointer)&base64Info,
      &base64);
    if (status != 0)
      break;

    /* If there's no key object yet, build it. If there is one, get the
     * key data.
     */
    if (envCtx->symKey == (VtKeyObject)0)
    {
      status = VT_ERROR_MEMORY;
      keyLen = (envCtx->symKeyBits + 7) / 8;
      keyData = (unsigned char *)Z2Malloc (keyLen, VOLT_MEMORY_SENSITIVE);
      if (keyData == (unsigned char *)0)
        break;

      status = VtGenerateRandomBytes (random, keyData, keyLen);
      if (status != 0)
        break;

      status = VtCreateKeyObject (
        (VtLibCtx)libCtx, VtKeyImplDefault, (Pointer)0, &(envCtx->symKey));
      if (status != 0)
        break;

      keyItem.data = keyData;
      keyItem.len = keyLen;
      status = VtSetKeyParam (
        envCtx->symKey, envCtx->SymKeyParam, (Pointer)&keyItem);
      if (status != 0)
        break;

      getKeyData = &keyItem;
    }
    else
    {
      status = VtGetKeyParam (
        envCtx->symKey, envCtx->SymKeyParam, (Pointer *)&getKeyData);
      if (status != 0)
        break;
    }

    /* How many recipients are there?
     */
    status = VtGetIdentityListCount (envCtx->recipList, &idCount, &maxIndex);
    if (status != 0)
      break;

    /* Build the array of recipientDatas. Use index as a temp variable.
     */
    status = VT_ERROR_MEMORY;
    index = idCount * sizeof (VoltRecipientData);
    envCtx->recipients = (VoltRecipientData *)Z2Malloc (index, 0);
    if (envCtx->recipients == (VoltRecipientData *)0)
      break;
    Z2Memset (envCtx->recipients, 0, index);
    envCtx->recipientsCount = idCount;

    /* Cycle through the identities, creating RecipientData for each.
     */
    indexD = 0;
    for (index = 0; index <= maxIndex; ++index)
    {
      status = VtGetIdentityListIdentity (
        envCtx->recipList, index, &currentId);
      if (status != 0)
      {
        /* If status is VT_ERROR_NO_ID_AT_INDEX, don't quit, just move
         * on to the next ID in the list.
         */
        if (status != VT_ERROR_NO_ID_AT_INDEX)
          break;
        status = 0;
        continue;
      }

      /* Make sure the identity is encoded. Calling this routine will
       * build the encoded ID internally, which is all we need. Use
       * keyLen as a temp variable. We're expecting the
       * BUFFER_TOO_SMALL error.
       */
      status = VtEncodeIdentity (
        currentId, VT_ENCODE_IBCS_2_V_DISTRICT, policyCtx,
        storageCtx, transportCtx, (unsigned char *)0, 0, &keyLen);
      if (status == 0)
        status = VT_ERROR_GENERAL;
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

      /* If this is a repeat identity, don't bother with it. Set it to
       * be inactive. Compare with all previously encoded ID's.
       * Use keyLen as a temp variable.
       */
      keyLen = 0;
      for (indexC = 0; indexC < index; ++indexC)
      {
        status = VtGetIdentityListIdentity (
          envCtx->recipList, indexC, &compareId);
        if (status != 0)
          continue;

        VoltIsSameIdentity (currentId, compareId, &keyLen);
        if (keyLen != 0)
          break;
      }

      /* If keyLen is not 0, there was a matching ID, ignore this
       * identity.
       */
      if (keyLen != 0)
      {
        VtSetEntryStatusInIdentityList (
          envCtx->recipList, index, VT_RECIPIENT_LIST_ENTRY_INACTIVE);
        continue;
      }

      /* Build the RecipientData struct for this identity.
       */
      envCtx->recipients[indexD].idRef = currentId;
      status =  VoltBuildRecipientData (
        obj, random, base64, getKeyData->data, getKeyData->len,
        &(envCtx->recipients[indexD]));
      if (status != 0)
        break;

      envCtx->totalRecipInfoLen += envCtx->recipients[indexD].recipInfoLen;

      indexD++;
    }
    if (status != 0)
      break;

    obj->state = VOLT_P7_STATE_ENV_WRITE_INIT;

  } while (0);

  VtDestroyAlgorithmObject (&base64);

  if (keyData != (unsigned char *)0)
    Z2Free (keyData);

  return (status);
}

int VoltP7EnvWriteUpdate (
   VtPkcs7Object pkcs7Obj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -