Back to index

lightning-sunbird  0.9+nobinonly
asn1cmn.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "nssrenam.h"
00038 #include "cmmf.h"
00039 #include "cmmfi.h"
00040 
00041 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
00042 SEC_ASN1_MKSUB(SEC_AnyTemplate)
00043 SEC_ASN1_MKSUB(SEC_IntegerTemplate)
00044 SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
00045 
00046 static const SEC_ASN1Template CMMFCertResponseTemplate[] = {
00047     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse)},
00048     { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId)},
00049     { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status), 
00050       CMMFPKIStatusInfoTemplate},
00051     { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER, 
00052       offsetof(CMMFCertResponse, certifiedKeyPair),
00053       CMMFCertifiedKeyPairTemplate},
00054     { 0 }
00055 };
00056 
00057 static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = {
00058     { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL, 
00059       sizeof(CMMFCertOrEncCert)},
00060     { 0 }
00061 };
00062 
00063 const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = {
00064     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair)},
00065     { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert),
00066       CMMFCertOrEncCertTemplate },
00067     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0,
00068       offsetof(CMMFCertifiedKeyPair, privateKey),
00069       CRMFEncryptedValueTemplate},
00070     { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 
00071       SEC_ASN1_XTRN | 1,
00072       offsetof (CMMFCertifiedKeyPair, derPublicationInfo),
00073       SEC_ASN1_SUB(SEC_AnyTemplate) },
00074     { 0 }
00075 };
00076 
00077 const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = {
00078     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo)},
00079     { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status)},
00080     { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING, 
00081       offsetof(CMMFPKIStatusInfo, statusString)},
00082     { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING, 
00083       offsetof(CMMFPKIStatusInfo, failInfo)},
00084     { 0 }
00085 };
00086 
00087 const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = {
00088     { SEC_ASN1_SEQUENCE_OF| SEC_ASN1_XTRN, 0, 
00089                      SEC_ASN1_SUB(SEC_SignedCertificateTemplate)}
00090 };
00091 
00092 const SEC_ASN1Template CMMFRandTemplate[] = {
00093     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand)},
00094     { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer)},
00095     { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash)},
00096     { 0 }
00097 };
00098 
00099 const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = {
00100     { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 
00101       offsetof(CMMFPOPODecKeyRespContent, responses),
00102       SEC_ASN1_SUB(SEC_IntegerTemplate), 
00103       sizeof(CMMFPOPODecKeyRespContent)},
00104     { 0 }
00105 };
00106 
00107 const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = {
00108     { SEC_ASN1_CONTEXT_SPECIFIC | 1,
00109       0,
00110       CRMFEncryptedValueTemplate},
00111     { 0 }
00112 };
00113 
00114 const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = {
00115     { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
00116       0,
00117       SEC_ASN1_SUB(SEC_SignedCertificateTemplate)},
00118     { 0 }
00119 };
00120 
00121 const SEC_ASN1Template CMMFCertRepContentTemplate[] = {
00122     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent)},
00123     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
00124       SEC_ASN1_CONTEXT_SPECIFIC | 1,
00125       offsetof(CMMFCertRepContent, caPubs),
00126       CMMFSequenceOfCertsTemplate },
00127     { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response),
00128       CMMFCertResponseTemplate},
00129     { 0 }
00130 };
00131 
00132 static const SEC_ASN1Template CMMFChallengeTemplate[] = {
00133     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge)},
00134     { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN, 
00135       offsetof(CMMFChallenge, owf),
00136       SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
00137     { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) },
00138     { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) },
00139     { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) },
00140     { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) },
00141     { 0 }
00142 };
00143 
00144 const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = {
00145     { SEC_ASN1_SEQUENCE_OF,offsetof(CMMFPOPODecKeyChallContent, challenges),
00146       CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) },
00147     { 0 }
00148 };
00149 
00150 SECStatus
00151 cmmf_decode_process_cert_response(PRArenaPool      *poolp, 
00152                               CERTCertDBHandle *db,
00153                               CMMFCertResponse *inCertResp)
00154 {
00155     SECStatus rv = SECSuccess;
00156   
00157     if (inCertResp->certifiedKeyPair != NULL) {
00158         rv = cmmf_decode_process_certified_key_pair(poolp, 
00159                                               db,
00160                                           inCertResp->certifiedKeyPair);
00161     }
00162     return rv;
00163 }
00164 
00165 static CERTCertificate*
00166 cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
00167 {
00168     CERTCertificate *newCert;
00169 
00170     newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE);
00171     return newCert;
00172 }
00173 
00174 static CMMFCertOrEncCertChoice
00175 cmmf_get_certorenccertchoice_from_der(SECItem *der)
00176 {
00177     CMMFCertOrEncCertChoice retChoice; 
00178 
00179     switch(der->data[0] & 0x0f) {
00180     case 0:
00181         retChoice = cmmfCertificate;
00182        break;
00183     case 1:
00184         retChoice = cmmfEncryptedCert;
00185        break;
00186     default:
00187         retChoice = cmmfNoCertOrEncCert;
00188        break;
00189     }
00190     return retChoice;
00191 }
00192 
00193 static SECStatus
00194 cmmf_decode_process_certorenccert(PRArenaPool       *poolp,
00195                               CERTCertDBHandle  *db,
00196                               CMMFCertOrEncCert *inCertOrEncCert)
00197 {
00198     SECStatus rv = SECSuccess;
00199 
00200     inCertOrEncCert->choice = 
00201         cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue);
00202 
00203     switch (inCertOrEncCert->choice) {
00204     case cmmfCertificate:
00205         {
00206            /* The DER has implicit tagging, so we gotta switch it to 
00207             * un-tagged in order for the ASN1 parser to understand it.
00208             * Saving the bits that were changed.
00209             */ 
00210            inCertOrEncCert->derValue.data[0] = 0x30;
00211            inCertOrEncCert->cert.certificate = 
00212                cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue);
00213            if (inCertOrEncCert->cert.certificate == NULL) {
00214                rv = SECFailure;
00215            }
00216        
00217        }
00218        break;
00219     case cmmfEncryptedCert:
00220        PORT_Assert(poolp);
00221        if (!poolp) {
00222            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00223            rv = SECFailure;
00224            break;
00225        }
00226         inCertOrEncCert->cert.encryptedCert =
00227            PORT_ArenaZNew(poolp, CRMFEncryptedValue);
00228        if (inCertOrEncCert->cert.encryptedCert == NULL) {
00229            rv = SECFailure;
00230            break;
00231        }
00232        rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert, 
00233                          CMMFCertOrEncCertEncryptedCertTemplate, 
00234                          (const char*)inCertOrEncCert->derValue.data,
00235                          inCertOrEncCert->derValue.len);
00236        break;
00237     default:
00238         rv = SECFailure;
00239     }
00240     return rv;
00241 }
00242 
00243 SECStatus 
00244 cmmf_decode_process_certified_key_pair(PRArenaPool          *poolp,
00245                                    CERTCertDBHandle     *db,
00246                                    CMMFCertifiedKeyPair *inCertKeyPair)
00247 {
00248     return cmmf_decode_process_certorenccert (poolp,
00249                                          db,
00250                                          &inCertKeyPair->certOrEncCert);
00251 }
00252 
00253