C2C background information

You should have read the other documents in this directory first before reading this one.

The certificate that comes back to the gateway url is one long string; for example,

MIICoDCCAgmgAwIBAQIFA6LWuW0wDQYJKoZIhvcNAQEEBQAwgbExCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTEcMBoGA1UEChMTQ29sdW1iaWEgVW5pdmVyc2l0eTENMAsGA1UECxMEQWNJUzEjMCEGA1UEAxMaQ29sdW1iaWEgVW5pdmVyc2l0eSBDT0QgQ0ExJTAjBgkqhkiG9w0BCQEWFmNlcnQtYXV0aEBjb2x1bWJpYS5lZHUwHhcNMDAxMjA1MjIwOTQ4WhcNMDAxMjA1MjIxNDQ4WjB2MQ8wDQYDVQQDEwZhcmllbDAxDTALBgNVBAsTBEFjSVMxHDAaBgNVBAoTE0NvbHVtYmlhIFVuaXZlcnNpdHkxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuX72G1Ck%2f01n8djOuLjI6Q10JvWhVcDj9jz6ezdOlhMXbzxtgd8rkaGFr7ZPilOgbLbFfabJZx2HVymlM6%2fUrTWCpQG2THjKWD%2bB5pAc0%2bEgOyNwDHQfbSFB7XhGjox1Qfvl%2f29euHclE6Zl0T%2bdqVrvE%2fPF9cwgLtcgPIMZJOkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQA4ht3AHWyuxKEXf%2fRB8vrsCG0%2f31%2f42YYjrgH%2fUiCt2PpRMJ%2fYH6sd7Wu%2bC5f%2fU8lww1JXYNKIBloZ2FWj6C3aPvdJr19WOZDeMyrKyTX4JGSnEuz9KRYzDYbSwHtM5uq%2frG1l1gUbxeI4AzbjsWsRcbZWjaLmjrozf3tpdwsDig%3d%3d

Notice also that it is url-encoded, as all variables received by a cgi script are.

In order to convert this to PEM format, you will need to url-decode it, add line feeds every 64th character, and add the BEGIN and END headers that PEM requires.

So your certificate would look something like this:

-----BEGIN CERTIFICATE-----
MIICoDCCAgmgAwIBAQIFA6LWuW0wDQYJKoZIhvcNAQEEBQAwgbExCzAJBgNVBAYT
AlVTMREwDwYDVQQIEwhOZXcgWW9yazEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTEc
MBoGA1UEChMTQ29sdW1iaWEgVW5pdmVyc2l0eTENMAsGA1UECxMEQWNJUzEjMCEG
A1UEAxMaQ29sdW1iaWEgVW5pdmVyc2l0eSBDT0QgQ0ExJTAjBgkqhkiG9w0BCQEW
FmNlcnQtYXV0aEBjb2x1bWJpYS5lZHUwHhcNMDAxMjA1MjIwOTQ4WhcNMDAxMjA1
MjIxNDQ4WjB2MQ8wDQYDVQQDEwZhcmllbDAxDTALBgNVBAsTBEFjSVMxHDAaBgNV
BAoTE0NvbHVtYmlhIFVuaXZlcnNpdHkxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkx
ETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAuX72G1Ck/01n8djOuLjI6Q10JvWhVcDj9jz6ezdOlhMXbzxt
gd8rkaGFr7ZPilOgbLbFfabJZx2HVymlM6/UrTWCpQG2THjKWD+B5pAc0+EgOyNw
DHQfbSFB7XhGjox1Qfvl/29euHclE6Zl0T+dqVrvE/PF9cwgLtcgPIMZJOkCAwEA
ATANBgkqhkiG9w0BAQQFAAOBgQA4ht3AHWyuxKEXf/RB8vrsCG0/31/42YYjrgH/
UiCt2PpRMJ/YH6sd7Wu+C5f/U8lww1JXYNKIBloZ2FWj6C3aPvdJr19WOZDeMyrK
yTX4JGSnEuz9KRYzDYbSwHtM5uq/rG1l1gUbxeI4AzbjsWsRcbZWjaLmjrozf3tp
dwsDig==
-----END CERTIFICATE-----

This PEM-format certificate is just base-64 encoding of the der-encoded raw certificate if you get rid of the line breaks and the headers again. Some (i.e. most) libraries will read PEM-formatted certificates directly, so putting it back into this form may be helpful; a sample (lousy) perl routine to do this is below.

sub convertcert2pem {
  my($cert) = @_;
  local $pemcertheader="-----BEGIN CERTIFICATE-----\n";
  local $pemcertfooter="-----END CERTIFICATE-----\n";
  local $pemcertbody=addlinebreaks($cert);
  local $pemcert = $pemcertheader.$pemcertbody.$pemcertfooter;
  return($pemcert);
}

sub addlinebreaks {
  my($cert)=@_;
  local $ll=64;
  local $certbody="";
  local $temp="";

  while (length($cert)>$ll) {
     $temp=substr($cert,0,$ll);
     $certbody = $certbody.$temp."\n";
     $cert=substr($cert,$ll);
  }
  $certbody = $certbody.$cert."\n";
  return($certbody);
}

I said that PEM encoding is base 64 encoding of a der-encoded object. DER stands for Distinguished Encoding Rules, and it describes a method of uniquely representing any given digital object as a binary string once the object can be described in the so-called ASN.1 (Abstract Syntax Notation).

The raw certificate is not readable; a cat -v which shows all of the control characters and so on as literal would display something like

0M-^B^B10M-^B^AM-^Z^B^E^BM-&^@^@^A0^M^F *M-^FHM-^FM-w^M^A^A^B^E^@0_1^K0 ^F^CU^D^F^S^BUS1^W0^U^F^CU^D
^S^NVeriSign, Inc.1705^F^CU^D^K^S.Class 4 Public Primary Certification Authority0^^^W^M960129000000Z^W^M991231235959Z0_1^K0   ^F^CU^D^F^S^BUS1^W0^U^F^CU^D
^S^NVeriSign, Inc.1705^F^CU^D^K^S.Class 4 Public Primary Certification Authority0M-^AM-^_0^M^F        *M-^FHM-^FM-w^M^A^A^A^E^@^CM-^AM-^M^@0M-^AM-    ^BM-^AM-^A^@M-PM-2uM-vxM-PM-.ZPM-tM-iPM-)M-^_M-
                         M-WM-oM-^QM-^TpM-hM-R$M-^PvM-  M-^EM-VM-_M-,M-f^A^W2M-^@M-pM-^]M-^SGM-^CM-jM-RM-^J$M-Q

which admittedly is not very enlightening.

In order to parse this thing you need to understand the structure of the certificate. The X.509 v3 spec says that the syntax for a certificate is as follows:

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

      TBSCertificate  ::=  SEQUENCE  {
           version         [0]  Version DEFAULT v1,
           serialNumber         CertificateSerialNumber,
           signature            AlgorithmIdentifier,
           issuer               Name,
           validity             Validity,
           subject              Name,
           subjectPublicKeyInfo SubjectPublicKeyInfo,
           issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                                -- If present, version shall be v2 or v3
           subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                                -- If present, version shall be v2 or v3
           extensions      [3]  Extensions OPTIONAL
                                -- If present, version shall be v3 --  }

You'll want to pay particular attention to the subject and extensions fields. The rest of the fields are useful for validation (for example) but most libraries have some routine that will do basic certificate validation for you.

Here is the definition for the subject field:


      Name            ::=   CHOICE { -- only one possibility for now --
                                       rdnSequence  RDNSequence }

      RDNSequence     ::=   SEQUENCE OF RelativeDistinguishedName

      DistinguishedName       ::=   RDNSequence

      RelativeDistinguishedName  ::=
                          SET SIZE (1 .. MAX) OF AttributeTypeAndValue

      AttributeTypeAndValue           ::=     SEQUENCE {
              type    AttributeType,
              value   AttributeValue }

      AttributeType           ::=   OBJECT IDENTIFIER

      AttributeValue          ::=   ANY

which is not all that helpful either. But generally this boils down to a sequence of things that usually has in it oid and value pairs for the fields CommonName, OrganizationalUnit, Organization, Locality, StateOrProvince, and Country. You'll want to extract the CommonName field and look at the value.

And here is the definition for the extensions field:

extension  ::=  SEQUENCE  {
           extnID      OBJECT IDENTIFIER,
           critical    BOOLEAN DEFAULT FALSE,
           extnValue   OCTET STRING  }

This is what we use to pack all the things into a certificate that didn't make it into the forst x.509 spec. The oid tells you what sort of thing it is, and the octet string contains.... the der-encoded value. That means, that for example, if you have an octet string which you want to put as a value into an extension, you der-encode the octet string *again* as an octet string (that's right, it would be double-encoded) and then stuff it in a sequence after its oid.

For more details about these oids, octet strings, and der-encoding and so on you had probably better look at the ASN.1 introduction and overview which is part fo some old SSLeay docs I have lying around. There is a pointer to the Layman's Guide to ASN.1 off of that page, which you will also want to read if you have to dig seriously into the guts of the certificate (for example, if your library doesn't have a mechanism for retrieving an arbitrary extension from the certificate getting its oid).