Exemple #1
0
static int
SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert, 
         PRBool encapsulated)
{
    char digestdata[32];
    unsigned int len;
    SECItem digest, data2sign;
    SEC_PKCS7ContentInfo *cinfo;
    SECStatus rv;

    if (outFile == NULL || inFile == NULL || cert == NULL)
	return -1;

    /* suck the file in */
	if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE) != SECSuccess)
	return -1;

    if (!encapsulated) {
	/* unfortunately, we must create the digest ourselves */
	/* SEC_PKCS7CreateSignedData should have a flag to not include */
	/* the content for non-encapsulated content at encode time, but */
	/* should always compute the hash itself */
	if (CreateDigest(&data2sign, digestdata, &len, 32) < 0)
	    return -1;
	digest.data = (unsigned char *)digestdata;
	digest.len = len;
    }

    /* XXX Need a better way to handle that usage stuff! */
    cinfo = SEC_PKCS7CreateSignedData (cert, certUsageEmailSigner, NULL,
				       SEC_OID_SHA1,
				       encapsulated ? NULL : &digest,
				       NULL, NULL);
    if (cinfo == NULL)
	return -1;

    if (encapsulated) {
	SEC_PKCS7SetContent(cinfo, (char *)data2sign.data, data2sign.len);
    }

    rv = SEC_PKCS7IncludeCertChain (cinfo, NULL);
    if (rv != SECSuccess) {
	SEC_PKCS7DestroyContentInfo (cinfo);
	return -1;
    }

    rv = SEC_PKCS7Encode (cinfo, SignOut, outFile, NULL,
			  NULL, &pwdata);

    SEC_PKCS7DestroyContentInfo (cinfo);

    if (rv != SECSuccess)
	return -1;

    return 0;
}
Exemple #2
0
SEC_PKCS7ContentInfo *
SECMIME_CreateSigned(CERTCertificate *scert,
                     CERTCertificate *ecert,
                     CERTCertDBHandle *certdb,
                     SECOidTag digestalg,
                     SECItem *digest,
                     SECKEYGetPasswordKey pwfn,
                     void *pwfn_arg)
{
    SEC_PKCS7ContentInfo *cinfo;
    SECStatus rv;

    /* See note in header comment above about digestalg. */
    /* Doesn't explain this. PORT_Assert (digestalg == SEC_OID_SHA1); */

    cinfo = SEC_PKCS7CreateSignedData(scert, certUsageEmailSigner,
                                      certdb, digestalg, digest,
                                      pwfn, pwfn_arg);
    if (cinfo == NULL)
        return NULL;

    if (SEC_PKCS7IncludeCertChain(cinfo, NULL) != SECSuccess) {
        SEC_PKCS7DestroyContentInfo(cinfo);
        return NULL;
    }

    /* if the encryption cert and the signing cert differ, then include
     * the encryption cert too.
     */
    /* it is ok to compare the pointers since we ref count, and the same
     * cert will always have the same pointer
     */
    if ((ecert != NULL) && (ecert != scert)) {
        rv = SEC_PKCS7AddCertificate(cinfo, ecert);
        if (rv != SECSuccess) {
            SEC_PKCS7DestroyContentInfo(cinfo);
            return NULL;
        }
    }
    /*
     * Add the signing time.  But if it fails for some reason,
     * may as well not give up altogether -- just assert.
     */
    rv = SEC_PKCS7AddSigningTime(cinfo);
    PORT_Assert(rv == SECSuccess);

    /*
     * Add the email profile.  Again, if it fails for some reason,
     * may as well not give up altogether -- just assert.
     */
    rv = smime_add_profile(ecert, cinfo);
    PORT_Assert(rv == SECSuccess);

    return cinfo;
}
Exemple #3
0
int 
jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, 
               char *password, JAR_FILE infp, JAR_FILE outfp)
{
    SEC_PKCS7ContentInfo *cinfo;
    const SECHashObject *hashObj;
    char *errstring;
    void *mw = NULL;
    void *hashcx;
    unsigned int len;
    int status = 0;
    SECStatus rv;
    SECItem digest;
    unsigned char digestdata[32];
    unsigned char buffer[4096];

    if (outfp == NULL || infp == NULL || cert == NULL)
	return JAR_ERR_GENERAL;

    /* we sign with SHA */
    hashObj = HASH_GetHashObject(HASH_AlgSHA1);

    hashcx = (* hashObj->create)();
    if (hashcx == NULL)
	return JAR_ERR_GENERAL;

    (* hashObj->begin)(hashcx);
    while (1) {
	int nb = JAR_FREAD(infp, buffer, sizeof buffer);
	if (nb == 0) { /* eof */
	    break;
	}
	(* hashObj->update) (hashcx, buffer, nb);
    }
    (* hashObj->end)(hashcx, digestdata, &len, 32);
    (* hashObj->destroy)(hashcx, PR_TRUE);

    digest.data = digestdata;
    digest.len = len;

    /* signtool must use any old context it can find since it's
	 calling from inside javaland. */
    PORT_SetError (0);
    cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL,
                                      SEC_OID_SHA1, &digest, NULL, mw);
    if (cinfo == NULL)
	return JAR_ERR_PK7;

    rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
    if (rv != SECSuccess) {
	status = PORT_GetError();
	SEC_PKCS7DestroyContentInfo(cinfo);
	return status;
    }

    /* Having this here forces signtool to always include signing time. */
    rv = SEC_PKCS7AddSigningTime(cinfo);
    /* don't check error */
    PORT_SetError(0);

    /* if calling from mozilla thread*/
    rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw);
    if (rv != SECSuccess)
	status = PORT_GetError();
    SEC_PKCS7DestroyContentInfo (cinfo);
    if (rv != SECSuccess) {
	errstring = JAR_get_error (status);
	return ((status < 0) ? status : JAR_ERR_GENERAL);
    }
    return 0;
}
Exemple #4
0
/**********************************************************************
 *
 * S i g n F i l e
 */
static int	
SignFile (FILE *outFile, FILE *inFile, CERTCertificate *cert)
{
    int	nb;
    char	ibuf[4096], digestdata[32];
    const SECHashObject *hashObj;
    void	*hashcx;
    unsigned int	len;

    SECItem digest;
    SEC_PKCS7ContentInfo * cinfo;
    SECStatus rv;

    if (outFile == NULL || inFile == NULL || cert == NULL)
	return - 1;

    /* XXX probably want to extend interface to allow other hash algorithms */
    hashObj = HASH_GetHashObject(HASH_AlgSHA1);

    hashcx = (*hashObj->create)();
    if (hashcx == NULL)
	return - 1;

    (*hashObj->begin)(hashcx);

    for (; ; ) {
	if (feof(inFile)) 
	    break;
	nb = fread(ibuf, 1, sizeof(ibuf), inFile);
	if (nb == 0) {
	    if (ferror(inFile)) {
		PORT_SetError(SEC_ERROR_IO);
		(*hashObj->destroy)(hashcx, PR_TRUE);
		return - 1;
	    }
	    /* eof */
	    break;
	}
	(*hashObj->update)(hashcx, (unsigned char *) ibuf, nb);
    }

    (*hashObj->end)(hashcx, (unsigned char *) digestdata, &len, 32);
    (*hashObj->destroy)(hashcx, PR_TRUE);

    digest.data = (unsigned char *) digestdata;
    digest.len = len;

    cinfo = SEC_PKCS7CreateSignedData 
        (cert, certUsageObjectSigner, NULL, 
        SEC_OID_SHA1, &digest, NULL, NULL);

    if (cinfo == NULL)
	return - 1;

    rv = SEC_PKCS7IncludeCertChain (cinfo, NULL);
    if (rv != SECSuccess) {
	SEC_PKCS7DestroyContentInfo (cinfo);
	return - 1;
    }

    if (no_time == 0) {
	rv = SEC_PKCS7AddSigningTime (cinfo);
	if (rv != SECSuccess) {
	    /* don't check error */
	}
    }

    rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL, NULL, &pwdata);

    SEC_PKCS7DestroyContentInfo (cinfo);

    if (rv != SECSuccess)
	return - 1;

    return 0;
}