Пример #1
0
/* Returns NULL if "encoding" cannot be decoded. */
NSS_IMPLEMENT nssDecodedCert *
nssDecodedPKIXCertificate_Create (
  NSSArena *arenaOpt,
  NSSDER *encoding
)
{
    nssDecodedCert  *rvDC = NULL;
    CERTCertificate *cert;
    SECItem          secDER;

    SECITEM_FROM_NSSITEM(&secDER, encoding);
    cert = CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
    if (cert) {
	rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
	if (rvDC) {
	    rvDC->type                = NSSCertificateType_PKIX;
	    rvDC->data                = (void *)cert;
	    rvDC->getIdentifier       = nss3certificate_getIdentifier;
	    rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
	    rvDC->matchIdentifier     = nss3certificate_matchIdentifier;
	    rvDC->isValidIssuer       = nss3certificate_isValidIssuer;
	    rvDC->getUsage            = nss3certificate_getUsage;
	    rvDC->isValidAtTime       = nss3certificate_isValidAtTime;
	    rvDC->isNewerThan         = nss3certificate_isNewerThan;
	    rvDC->matchUsage          = nss3certificate_matchUsage;
	    rvDC->isTrustedForUsage   = nss3certificate_isTrustedForUsage;
	    rvDC->getEmailAddress     = nss3certificate_getEmailAddress;
	    rvDC->getDERSerialNumber  = nss3certificate_getDERSerialNumber;
	} else {
	    CERT_DestroyCertificate(cert);
	}
    }
    return rvDC;
}
/* From certdb.c */
static SECStatus
cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool trusted)
{
    SECStatus rv;
    SECItem *derCert;
    CERTCertificate *cert = NULL;
    CERTCertificate *newcert = NULL;
    CERTCertDBHandle *handle;
    CERTCertTrust trust;
    PRBool isca;
    char *nickname;
    unsigned int certtype;
    
    handle = CERT_GetDefaultCertDB();
    
    while (numcerts--) {
	derCert = certs;
	certs++;

	/* decode my certificate */
	/* This use is ok -- only looks at decoded parts, calls NewTemp later */
	newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
	if ( newcert == NULL ) {
	    goto loser;
	}

	if (!trusted) {
	    /* make sure that cert is valid */
	    rv = CERT_CertTimesValid(newcert);
	    if ( rv == SECFailure ) {
		goto endloop;
	    }
	}

	/* does it have the CA extension */
	
	/*
	 * Make sure that if this is an intermediate CA in the chain that
	 * it was given permission by its signer to be a CA.
	 */
	isca = CERT_IsCACert(newcert, &certtype);

	if ( !isca ) {
	    if (!trusted) {
		goto endloop;
	    }
	    trust.sslFlags = CERTDB_VALID_CA;
	    trust.emailFlags = CERTDB_VALID_CA;
	    trust.objectSigningFlags = CERTDB_VALID_CA;
	} else {
	    /* SSL ca's must have the ssl bit set */
	    if ( ( certUsage == certUsageSSLCA ) &&
		(( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA )) {
		goto endloop;
	    }

	    /* it passed all of the tests, so lets add it to the database */
	    /* mark it as a CA */
	    PORT_Memset((void *)&trust, 0, sizeof(trust));
	    switch ( certUsage ) {
	      case certUsageSSLCA:
		trust.sslFlags = CERTDB_VALID_CA;
		break;
	      case certUsageUserCertImport:
		if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
		    trust.sslFlags = CERTDB_VALID_CA;
		}
		if ((certtype & NS_CERT_TYPE_EMAIL_CA) 
						== NS_CERT_TYPE_EMAIL_CA ) {
		    trust.emailFlags = CERTDB_VALID_CA;
		}
		if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) ==
					NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
		     trust.objectSigningFlags = CERTDB_VALID_CA;
		}
		break;
	      default:
		PORT_Assert(0);
		break;
	    }
	}
	
	cert = CERT_NewTempCertificate(handle, derCert, NULL, 
							PR_FALSE, PR_FALSE);
	if ( cert == NULL ) {
	    goto loser;
	}
	
	/* if the cert is temp, make it perm; otherwise we're done */
	if (cert->istemp) {
	    /* get a default nickname for it */
	    nickname = CERT_MakeCANickname(cert);

	    rv = CERT_AddTempCertToPerm(cert, nickname, &trust);

	    /* free the nickname */
	    if ( nickname ) {
		PORT_Free(nickname);
	    }
	} else {
	    rv = SECSuccess;
	}

	CERT_DestroyCertificate(cert);
	cert = NULL;
	
	if ( rv != SECSuccess ) {
	    goto loser;
	}

endloop:
	if ( newcert ) {
	    CERT_DestroyCertificate(newcert);
	    newcert = NULL;
	}
	
    }

    rv = SECSuccess;
    goto done;
loser:
    rv = SECFailure;
done:
    
    if ( newcert ) {
	CERT_DestroyCertificate(newcert);
	newcert = NULL;
    }
    
    if ( cert ) {
	CERT_DestroyCertificate(cert);
	cert = NULL;
    }
    
    return(rv);
}
Пример #3
0
static SECStatus
ConvertCertificate(SECItem *sdder, char *nickname, CERTCertTrust *trust,
                   PRBool excludeCert, PRBool excludeHash)
{
    SECStatus rv = SECSuccess;
    CERTCertificate *cert;
    unsigned char sha1_hash[SHA1_LENGTH];
    unsigned char md5_hash[MD5_LENGTH];
    SECItem *serial = NULL;
    PRBool step_up = PR_FALSE;
    const char *trust_info;

    cert = CERT_DecodeDERCertificate(sdder, PR_FALSE, nickname);
    if (!cert) {
	return SECFailure;
    }
    serial = SEC_ASN1EncodeItem(NULL,NULL,cert,serialTemplate);
    if (!serial) {
	return SECFailure;
    }
    
    if (!excludeCert) {
	printf("\n#\n# Certificate \"%s\"\n#\n",nickname);
	print_info(sdder, cert);
	printf("CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE\n");
	printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
	printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
	printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
	printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
	printf("CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509\n");
	printf("CKA_SUBJECT MULTILINE_OCTAL\n");
	dumpbytes(cert->derSubject.data,cert->derSubject.len);
	printf("END\n");
	printf("CKA_ID UTF8 \"0\"\n");
	printf("CKA_ISSUER MULTILINE_OCTAL\n");
	dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
	printf("END\n");
	printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
	dumpbytes(serial->data,serial->len);
	printf("END\n");
	printf("CKA_VALUE MULTILINE_OCTAL\n");
	dumpbytes(sdder->data,sdder->len);
	printf("END\n");
    }
    
    if ((trust->sslFlags | trust->emailFlags | trust->objectSigningFlags) 
         == CERTDB_TERMINAL_RECORD)
      trust_info = "Distrust";
    else
      trust_info = "Trust for";
    
    printf("\n# %s \"%s\"\n", trust_info, nickname);
    print_info(sdder, cert);

    printf("CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST\n");
    printf("CKA_TOKEN CK_BBOOL CK_TRUE\n");
    printf("CKA_PRIVATE CK_BBOOL CK_FALSE\n");
    printf("CKA_MODIFIABLE CK_BBOOL CK_FALSE\n");
    printf("CKA_LABEL UTF8 \"%s\"\n",nickname);
    
    if (!excludeHash) {
	PK11_HashBuf(SEC_OID_SHA1, sha1_hash, sdder->data, sdder->len);
	printf("CKA_CERT_SHA1_HASH MULTILINE_OCTAL\n");
	dumpbytes(sha1_hash,SHA1_LENGTH);
	printf("END\n");
	PK11_HashBuf(SEC_OID_MD5, md5_hash, sdder->data, sdder->len);
	printf("CKA_CERT_MD5_HASH MULTILINE_OCTAL\n");
	dumpbytes(md5_hash,MD5_LENGTH);
	printf("END\n");
    }

    printf("CKA_ISSUER MULTILINE_OCTAL\n");
    dumpbytes(cert->derIssuer.data,cert->derIssuer.len);
    printf("END\n");
    printf("CKA_SERIAL_NUMBER MULTILINE_OCTAL\n");
    dumpbytes(serial->data,serial->len);
    printf("END\n");
    
    printf("CKA_TRUST_SERVER_AUTH CK_TRUST %s\n",
				getTrustString(trust->sslFlags));
    printf("CKA_TRUST_EMAIL_PROTECTION CK_TRUST %s\n",
				getTrustString(trust->emailFlags));
    printf("CKA_TRUST_CODE_SIGNING CK_TRUST %s\n",
				getTrustString(trust->objectSigningFlags));
#ifdef notdef
    printf("CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NSS_TRUSTED\n");
    printf("CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
    printf("CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
    printf("CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
    printf("CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
    printf("CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
    printf("CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NSS_TRUSTED_DELEGATOR\n");
#endif
    
    step_up = (trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
    printf("CKA_TRUST_STEP_UP_APPROVED CK_BBOOL %s\n",
                step_up ? "CK_TRUE" : "CK_FALSE");

    PORT_Free(sdder->data);
    return(rv);

}