000022119 - How to get the signature value from a certificate in Cert-C

Document created by RSA Customer Support Employee on Jun 16, 2016Last modified by RSA Customer Support Employee on Apr 21, 2017
Version 2Show Document
  • View in full screen mode

Article Content

Article Number000022119
Applies ToRSA BSAFE Cert-C 2.7
IssueHow to get the signature value from a certificate in Cert-C
Resolution

Use the ASN.1 functions in Cert-C.  For example, modifyvthe cert.c sample program, by adding code to ExtractObjsFromCert() that calls C_BERDecodeList(), C_GetListObjectEntry(), and C_BERDecodeBitString(). (There is similar code in SAMPLES\pkcs10\pkcs10.c, in the VerifyPkcs10Signature2() function.)

Here is the code to add to the ExtractObjsFromCert() function in the cert.c sample program.

diff of samples\cert\cert.c

324a325,333
  /* CHANGE/ADD: Code to extract the certificate signature */
  LIST_OBJ decodedList = NULL;
  int tag;
  unsigned int tagClass;
  unsigned int count;
  ITEM *tbsCertificateItemPtr = NULL, *signatureAlgorithmItemPtr = NULL,
    *signatureItemPtr = NULL;
  BIT_STRING signatureBitString = {NULL, 0, 0};


396a406,488
  /* CHANGE/ADD: Code to extract the certificate signature */
  /* We can actually skip most of the checking below, because C_SetCertBER has
       already passed */

  /* A Certificate is defined as

  Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signature            BIT STRING  }
   */

  /* Create a list object for storing the three components of the SEQUENCE */
  status = C_CreateListObject (&decodedList);
  if (status != 0)
    goto CLEANUP;

  /* Decode the SEQUENCE into a list object containing three components */
  status = C_BERDecodeList (ctx, certBer, certBerLen, &tag, &tagClass, decodedList);
  if (status != 0)
    goto CLEANUP;

  /* The value is a Certificate, which is a SEQUENCE */
  if (tag != VT_SEQUENCE) {
    status = RSA_DEMO_E_INVALID_TAG;
    goto CLEANUP;
  }

  /* The list should contain three components */
  status = C_GetListObjectCount (decodedList, &count);
  if (status != 0)
    goto CLEANUP;

  if (count != 3) {
    /* Not really an invalid tag, but reuse this error for simplicity */
    status = RSA_DEMO_E_INVALID_TAG;
    goto CLEANUP;
  }

  /* The first component is a TBSCertificate, which is a SEQUENCE */
  status = C_GetListObjectEntry (decodedList, 0, (POINTER *)&tbsCertificateItemPtr);
  if (status != 0)
    goto CLEANUP;

  /* The second component is an AlgorithmIdentifier, which is a SEQUENCE */
  status = C_GetListObjectEntry (decodedList, 1, (POINTER *)&signatureAlgorithmItemPtr);
  if (status != 0)
    goto CLEANUP;

  /* The third component is the signature, which is a BIT STRING */
  status = C_GetListObjectEntry (decodedList, 2, (POINTER *)&signatureItemPtr);
  if (status != 0)
    goto CLEANUP;

  /* Decode the BIT STRING to get just the value */
  status = C_BERDecodeBitString (ctx, signatureItemPtr->data, signatureItemPtr->len, &tag,
                                 &tagClass, &signatureBitString );
  if (status != 0)
    goto CLEANUP;

  if (tag != VT_BIT_STRING) {
    status = RSA_DEMO_E_INVALID_TAG;
    goto CLEANUP;
  }

  /* Right now, we only handle the case where unused bits is 0.  I've never
     seen a signature value whose unused bits is non-zero. */
  if (signatureBitString.unusedBits != 0) {
    status = RSA_DEMO_E_NOT_IMPLEMENTED;
    goto CLEANUP;
  }

  RSA_PrintBuf ("Certificate signature", signatureBitString.data, signatureBitString.len);
  status = RSA_WriteDataToFile
           (signatureBitString.data, signatureBitString.len, "Enter name of file to store certificate signature binary");
  if (status == RSA_DEMO_E_CANCEL)
    status = 0; /* you don't have to save if you don't want to */
  else if (status != 0)
    goto CLEANUP;

  /* END CHANGE/ADD: Code to extract the certificate signature */

405a498,500
  /* CHANGE/ADD: Code to extract the certificate signature */
  C_DestroyListObject (&decodedList);

Legacy Article IDa26946

Attachments

    Outcomes