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
/*
 * Start an S/MIME encrypting context.
 *
 * "scert" is the cert for the sender.  It will be checked for validity.
 * "rcerts" are the certs for the recipients.  They will also be checked.
 *
 * "certdb" is the cert database to use for verifying the certs.
 * It can be NULL if a default database is available (like in the client).
 *
 * This function already does all of the stuff specific to S/MIME protocol
 * and local policy; the return value just needs to be passed to
 * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
 * and finally to SEC_PKCS7DestroyContentInfo().
 *
 * An error results in a return value of NULL and an error set.
 * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
 */
SEC_PKCS7ContentInfo *
SECMIME_CreateEncrypted(CERTCertificate *scert,
                        CERTCertificate **rcerts,
                        CERTCertDBHandle *certdb,
                        SECKEYGetPasswordKey pwfn,
                        void *pwfn_arg)
{
    SEC_PKCS7ContentInfo *cinfo;
    long cipher;
    SECOidTag encalg;
    int keysize;
    int mapi, rci;

    cipher = smime_choose_cipher(scert, rcerts);
    if (cipher < 0)
        return NULL;

    mapi = smime_mapi_by_cipher(cipher);
    if (mapi < 0)
        return NULL;

    /*
     * XXX This is stretching it -- CreateEnvelopedData should probably
     * take a cipher itself of some sort, because we cannot know what the
     * future will bring in terms of parameters for each type of algorithm.
     * For example, just an algorithm and keysize is *not* sufficient to
     * fully specify the usage of RC5 (which also needs to know rounds and
     * block size).  Work this out into a better API!
     */
    encalg = smime_cipher_maps[mapi].algtag;
    keysize = smime_keysize_by_cipher(cipher);
    if (keysize < 0)
        return NULL;

    cinfo = SEC_PKCS7CreateEnvelopedData(scert, certUsageEmailRecipient,
                                         certdb, encalg, keysize,
                                         pwfn, pwfn_arg);
    if (cinfo == NULL)
        return NULL;

    for (rci = 0; rcerts[rci] != NULL; rci++) {
        if (rcerts[rci] == scert)
            continue;
        if (SEC_PKCS7AddRecipient(cinfo, rcerts[rci], certUsageEmailRecipient,
                                  NULL) != SECSuccess) {
            SEC_PKCS7DestroyContentInfo(cinfo);
            return NULL;
        }
    }

    return cinfo;
}
static int
HashDecodeAndVerify(FILE *out, FILE *content, PRFileDesc *signature,
		    SECCertUsage usage, char *progName)
{
    SECItem derdata;
    SEC_PKCS7ContentInfo *cinfo;
    SEC_PKCS7SignedData *signedData;
    HASH_HashType digestType;
    SECItem digest;
    unsigned char buffer[32];

    if (SECU_ReadDERFromFile(&derdata, signature, PR_FALSE) != SECSuccess) {
	SECU_PrintError(progName, "error reading signature file");
	return -1;
    }

    cinfo = SEC_PKCS7DecodeItem(&derdata, NULL, NULL, NULL, NULL,
				NULL, NULL, NULL);
    if (cinfo == NULL)
	return -1;

    if (! SEC_PKCS7ContentIsSigned(cinfo)) {
	fprintf (out, "Signature file is pkcs7 data, but not signed.\n");
	return -1;
    }

    signedData = cinfo->content.signedData;

    /* assume that there is only one digest algorithm for now */
    digestType = AlgorithmToHashType(signedData->digestAlgorithms[0]);
    if (digestType == HASH_AlgNULL) {
	fprintf (out, "Invalid hash algorithmID\n");
	return -1;
    }

    digest.data = buffer;
    if (DigestFile (digest.data, &digest.len, 32, content, digestType)) {
	SECU_PrintError (progName, "problem computing message digest");
	return -1;
    }

    fprintf(out, "Signature is ");
    if (SEC_PKCS7VerifyDetachedSignature (cinfo, usage, &digest, digestType,
					  PR_FALSE))
	fprintf(out, "valid.\n");
    else
	fprintf(out, "invalid (Reason: %s).\n",
		SECU_Strerror(PORT_GetError()));

    SEC_PKCS7DestroyContentInfo(cinfo);
    return 0;
}
Exemple #5
0
int
SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der)
{
    SEC_PKCS7ContentInfo *cinfo;
    int rv = -1;

    cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

    if (cinfo != NULL) {
        rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo=");
        SEC_PKCS7DestroyContentInfo(cinfo);
    }

    return rv;
}
SECStatus
SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg)
{
    SEC_PKCS7ContentInfo *contentInfo = NULL;
    SECStatus rv;
    SECItem **certs;
    int count;

    contentInfo = SEC_PKCS7DecodeItem(pkcs7Item, NULL, NULL, NULL, NULL, NULL, 
				      NULL, NULL);
    if ( contentInfo == NULL ) {
	goto loser;
    }

    if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) {
	goto loser;
    }

    certs = contentInfo->content.signedData->rawCerts;
    if ( certs ) {
	count = 0;
	
	while ( *certs ) {
	    count++;
	    certs++;
	}
	rv = (* f)(arg, contentInfo->content.signedData->rawCerts, count);
    }
    
    rv = SECSuccess;
    
    goto done;
loser:
    rv = SECFailure;
    
done:
    if ( contentInfo ) {
	SEC_PKCS7DestroyContentInfo(contentInfo);
    }

    return(rv);
}
Exemple #7
0
static SECStatus
crmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit)
{
    PORT_Assert(inEncrKey != NULL);
    if (inEncrKey != NULL) {
        switch (inEncrKey->encKeyChoice) {
        case crmfEncryptedValueChoice:
            crmf_destroy_encrypted_value(&inEncrKey->value.encryptedValue,
                                         PR_FALSE);
            break;
        case crmfEnvelopedDataChoice:
            SEC_PKCS7DestroyContentInfo(inEncrKey->value.envelopedData);
            break;
        default:
            break;
        }
        if (freeit) {
            PORT_Free(inEncrKey);
        }
    }
    return SECSuccess;
}
Exemple #8
0
static int
EncryptFile(FILE *outFile, FILE *inFile, struct recipient *recipients,
	    char *progName)
{
    SEC_PKCS7ContentInfo *cinfo;
    SEC_PKCS7EncoderContext *ecx;
    struct recipient *rcpt;
    SECStatus rv;

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

    /* XXX Need a better way to handle that certUsage stuff! */
    /* XXX keysize? */
    cinfo = SEC_PKCS7CreateEnvelopedData (recipients->cert,
					  certUsageEmailRecipient,
					  NULL, SEC_OID_DES_EDE3_CBC, 0, 
					  NULL, NULL);
    if (cinfo == NULL)
	return -1;

    for (rcpt = recipients->next; rcpt != NULL; rcpt = rcpt->next) {
	rv = SEC_PKCS7AddRecipient (cinfo, rcpt->cert, certUsageEmailRecipient,
				    NULL);
	if (rv != SECSuccess) {
	    SECU_PrintError(progName, "error adding recipient \"%s\"",
			    rcpt->nickname);
	    return -1;
	}
    }

    ecx = SEC_PKCS7EncoderStart (cinfo, EncryptOut, outFile, NULL);
    if (ecx == NULL)
	return -1;

    for (;;) {
	char ibuf[1024];
	int nb;
 
	if (feof(inFile))
	    break;
	nb = fread(ibuf, 1, sizeof(ibuf), inFile);
	if (nb == 0) {
	    if (ferror(inFile)) {
		PORT_SetError(SEC_ERROR_IO);
		rv = SECFailure;
	    }
	    break;
	}
	rv = SEC_PKCS7EncoderUpdate(ecx, ibuf, nb);
	if (rv != SECSuccess)
	    break;
    }

    if (SEC_PKCS7EncoderFinish(ecx, NULL, NULL) != SECSuccess)
	rv = SECFailure;

    SEC_PKCS7DestroyContentInfo (cinfo);

    if (rv != SECSuccess)
	return -1;

    return 0;
}
Exemple #9
0
/*************************************************************************
 *
 * o u t p u t _ c a _ c e r t
 */
static void	
output_ca_cert (CERTCertificate *cert, CERTCertDBHandle *db)
{
    FILE * out;

    SECItem * encodedCertChain;
    SEC_PKCS7ContentInfo * certChain;
    char	*filename;

    /* the raw */

    filename = PORT_ZAlloc(strlen(DEFAULT_X509_BASENAME) + 8);
    if (!filename) 
	out_of_memory();

    sprintf(filename, "%s.raw", DEFAULT_X509_BASENAME);
    if ((out = fopen (filename, "wb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
	     filename);
	errorCount++;
	exit(ERRX);
    }

    certChain = SEC_PKCS7CreateCertsOnly (cert, PR_TRUE, db);
    encodedCertChain 
         = SEC_PKCS7EncodeItem (NULL, NULL, certChain, NULL, NULL, NULL);
    SEC_PKCS7DestroyContentInfo (certChain);

    if (encodedCertChain) {
	fprintf(out, "Content-type: application/x-x509-ca-cert\n\n");
	fwrite (encodedCertChain->data, 1, encodedCertChain->len,
	     out);
	SECITEM_FreeItem(encodedCertChain, PR_TRUE);
    } else {
	PR_fprintf(errorFD, "%s: Can't DER encode this certificate\n",
	     PROGRAM_NAME);
	errorCount++;
	exit(ERRX);
    }

    fclose (out);

    /* and the cooked */

    sprintf(filename, "%s.cacert", DEFAULT_X509_BASENAME);
    if ((out = fopen (filename, "wb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
	     filename);
	errorCount++;
	return;
    }

    fprintf (out, "%s\n%s\n%s\n", 
        NS_CERT_HEADER,
        BTOA_DataToAscii (cert->derCert.data, cert->derCert.len), 
        NS_CERT_TRAILER);

    fclose (out);

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "Exported certificate to %s.raw and %s.cacert.\n",
	     			DEFAULT_X509_BASENAME, DEFAULT_X509_BASENAME);
    }
}
Exemple #10
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;
}
int main(int argc, char **argv)
{
    PRFileDesc *contentFile = NULL;
    PRFileDesc *signFile = PR_STDIN;
    FILE *	outFile  = stdout;
    char *	progName;
    SECStatus	rv;
    int 	result	 = 1;
    SECItem	pkcs7der, content;
    secuCommand signver;

    pkcs7der.data  = NULL;
    content.data = NULL;

    signver.numCommands = sizeof(signver_commands) /sizeof(secuCommandFlag);
    signver.numOptions = sizeof(signver_options) / sizeof(secuCommandFlag);
    signver.commands = signver_commands;
    signver.options = signver_options;

#ifdef XP_PC
    progName = strrchr(argv[0], '\\');
#else
    progName = strrchr(argv[0], '/');
#endif
    progName = progName ? progName+1 : argv[0];

    rv = SECU_ParseCommandLine(argc, argv, progName, &signver);
    if (SECSuccess != rv) {
	Usage(progName, outFile);
    }
    debugInfo = signver.options[opt_DebugInfo	    ].activated;
    verbose   = signver.options[opt_PrintWhyFailure ].activated;
    doVerify  = signver.commands[cmd_VerifySignedObj].activated;
    displayAll= signver.commands[cmd_DisplayAllPCKS7Info].activated;
    if (!doVerify && !displayAll)
	doVerify = PR_TRUE;

    /*	Set the certdb directory (default is ~/.netscape) */
    rv = NSS_Init(SECU_ConfigDirectory(signver.options[opt_CertDir].arg));
    if (rv != SECSuccess) {
	SECU_PrintPRandOSError(progName);
	return result;
    }
    /* below here, goto cleanup */
    SECU_RegisterDynamicOids();

    /*	Open the input content file. */
    if (signver.options[opt_InputDataFile].activated &&
	signver.options[opt_InputDataFile].arg) {
	if (PL_strcmp("-", signver.options[opt_InputDataFile].arg)) {
	    contentFile = PR_Open(signver.options[opt_InputDataFile].arg,
			       PR_RDONLY, 0);
	    if (!contentFile) {
		PR_fprintf(PR_STDERR,
			   "%s: unable to open \"%s\" for reading.\n",
			   progName, signver.options[opt_InputDataFile].arg);
		goto cleanup;
	    }
	} else
	    contentFile = PR_STDIN;
    }

    /*	Open the input signature file.	*/
    if (signver.options[opt_InputSigFile].activated &&
	signver.options[opt_InputSigFile].arg) {
	if (PL_strcmp("-", signver.options[opt_InputSigFile].arg)) {
	    signFile = PR_Open(signver.options[opt_InputSigFile].arg,
			       PR_RDONLY, 0);
	    if (!signFile) {
		PR_fprintf(PR_STDERR,
			   "%s: unable to open \"%s\" for reading.\n",
			   progName, signver.options[opt_InputSigFile].arg);
		goto cleanup;
	    }
	}
    }

    if (contentFile == PR_STDIN && signFile == PR_STDIN && doVerify) {
	PR_fprintf(PR_STDERR,
	    "%s: cannot read both content and signature from standard input\n",
		   progName);
	goto cleanup;
    }

    /*	Open|Create the output file.  */
    if (signver.options[opt_OutputFile].activated) {
	outFile = fopen(signver.options[opt_OutputFile].arg, "w");
	if (!outFile) {
	    PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for writing.\n",
		       progName, signver.options[opt_OutputFile].arg);
	    goto cleanup;
	}
    }

    /* read in the input files' contents */
    rv = SECU_ReadDERFromFile(&pkcs7der, signFile,
			      signver.options[opt_ASCII].activated);
    if (signFile != PR_STDIN)
	PR_Close(signFile);
    if (rv != SECSuccess) {
	SECU_PrintError(progName, "problem reading PKCS7 input");
	goto cleanup;
    }
    if (contentFile) {
	rv = SECU_FileToItem(&content, contentFile);
	if (contentFile != PR_STDIN)
	    PR_Close(contentFile);
	if (rv != SECSuccess)
	    content.data = NULL;
    }

    /* Signature Verification */
    if (doVerify) {
	SEC_PKCS7ContentInfo *cinfo;
	SEC_PKCS7SignedData *signedData;
	HASH_HashType digestType;
	PRBool contentIsSigned;

	cinfo = SEC_PKCS7DecodeItem(&pkcs7der, NULL, NULL, NULL, NULL,
				    NULL, NULL, NULL);
	if (cinfo == NULL) {
	    PR_fprintf(PR_STDERR, "Unable to decode PKCS7 data\n");
	    goto cleanup;
	}
	/* below here, goto done */

	contentIsSigned = SEC_PKCS7ContentIsSigned(cinfo);
	if (debugInfo) {
	    PR_fprintf(PR_STDERR, "Content is%s encrypted.\n",
		       SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
	}
	if (debugInfo || !contentIsSigned) {
	    PR_fprintf(PR_STDERR, "Content is%s signed.\n",
		       contentIsSigned ? "" : " not");
	}

	if (!contentIsSigned)
	    goto done;

	signedData = cinfo->content.signedData;

	/* assume that there is only one digest algorithm for now */
	digestType = AlgorithmToHashType(signedData->digestAlgorithms[0]);
	if (digestType == HASH_AlgNULL) {
	    PR_fprintf(PR_STDERR, "Invalid hash algorithmID\n");
	    goto done;
	}
	if (content.data) {
	    SECCertUsage   usage = certUsageEmailSigner;
	    SECItem	   digest;
	    unsigned char  digestBuffer[HASH_LENGTH_MAX];

	    if (debugInfo)
		PR_fprintf(PR_STDERR, "contentToVerify=%s\n", content.data);

	    digest.data = digestBuffer;
	    digest.len	= sizeof digestBuffer;

	    if (DigestContent(&digest, &content, digestType)) {
		SECU_PrintError(progName, "Message digest computation failure");
		goto done;
	    }

	    if (debugInfo) {
		unsigned int i;
		PR_fprintf(PR_STDERR, "Data Digest=:");
		for (i = 0; i < digest.len; i++)
		    PR_fprintf(PR_STDERR, "%02x:", digest.data[i]);
		PR_fprintf(PR_STDERR, "\n");
	    }

	    fprintf(outFile, "signatureValid=");
	    PORT_SetError(0);
	    if (SEC_PKCS7VerifyDetachedSignature (cinfo, usage,
				   &digest, digestType, PR_FALSE)) {
		fprintf(outFile, "yes");
	    } else {
		fprintf(outFile, "no");
		if (verbose) {
		    fprintf(outFile, ":%s",
			    SECU_Strerror(PORT_GetError()));
		}
	    }
	    fprintf(outFile, "\n");
	    result = 0;
	}
done:
	SEC_PKCS7DestroyContentInfo(cinfo);
    }

    if (displayAll) {
	if (SV_PrintPKCS7ContentInfo(outFile, &pkcs7der))
	    result = 1;
    }

cleanup:
    SECITEM_FreeItem(&pkcs7der, PR_FALSE);
    SECITEM_FreeItem(&content, PR_FALSE);

    if (NSS_Shutdown() != SECSuccess) {
	result = 1;
    }

    return result;
}
Exemple #12
0
void
pesign_context_fini(pesign_context *ctx)
{
	if (!ctx)
		return;

	if (ctx->cms_ctx) {
		cms_context_fini(ctx->cms_ctx);
		ctx->cms_ctx = NULL;
	}

	if (ctx->outpe) {
		pe_end(ctx->outpe);
		ctx->outpe = NULL;
	}

	if (ctx->inpe) {
		pe_end(ctx->inpe);
		ctx->inpe = NULL;
	}

	xfree(ctx->outfile);
	xfree(ctx->infile);

	xfree(ctx->rawsig);
	xfree(ctx->insattrs);
	xfree(ctx->outsattrs);

	xfree(ctx->insig);
	xfree(ctx->outsig);

	xfree(ctx->outkey);
	xfree(ctx->outcert);

	if (ctx->rawsigfd >= 0) {
		close(ctx->rawsigfd);
		ctx->rawsigfd = -1;
	}
	if (ctx->insattrsfd >= 0) {
		close(ctx->insattrsfd);
		ctx->insattrsfd = -1;
	}
	if (ctx->outsattrsfd >= 0) {
		close(ctx->outsattrsfd);
		ctx->outsattrsfd = -1;
	}

	if (ctx->insigfd >= 0) {
		close(ctx->insigfd);
		ctx->insigfd = -1;
	}

	if (ctx->outsigfd >= 0) {
		close(ctx->outsigfd);
		ctx->outsigfd = -1;
	}

	if (ctx->outkeyfd >= 0) {
		close(ctx->outkeyfd);
		ctx->outkeyfd = -1;
	}

	if (ctx->outcertfd >= 0) {
		close(ctx->outcertfd);
		ctx->outcertfd = -1;
	}

	if (ctx->cinfo) {
		SEC_PKCS7DestroyContentInfo(ctx->cinfo);
		ctx->cinfo = NULL;
	}

	if (ctx->outfd >= 0) {
		close(ctx->outfd);
		ctx->outfd = -1;
	}

	if (ctx->infd >= 0) {
		close(ctx->infd);
		ctx->infd = -1;
	}

	ctx->signum = -1;

	if (!(ctx->flags & PESIGN_C_ALLOCATED))
		pesign_context_init(ctx);

}
Exemple #13
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;
}
Exemple #14
0
smime_CMDExports() {
	SEC_PKCS7DecodeItem();
	SEC_PKCS7DestroyContentInfo();
}
Exemple #15
0
int
list_signatures(pesign_context *ctx)
{
	cert_iter iter;

	int rc = cert_iter_init(&iter, ctx->inpe);

	if (rc < 0) {
		printf("No certificate list found.\n");
		return rc;
	}

	void *data;
	ssize_t datalen;
	int nsigs = 0;

	rc = 0;
	while (1) {
		rc = next_cert(&iter, &data, &datalen);
		if (rc <= 0)
			break;

		SEC_PKCS7DecoderContext *dc = NULL;
		saw_content = 0;
		dc = SEC_PKCS7DecoderStart(handle_bytes, NULL, NULL, NULL,
					NULL, NULL, decryption_allowed);

		if (dc == NULL) {
			fprintf(stderr, "SEC_PKCS7DecoderStart failed\n");
			exit(1);
		}

		SECStatus status = SEC_PKCS7DecoderUpdate(dc, data, datalen);

		if (status != SECSuccess) {
			fprintf(stderr, "Found invalid certificate\n");
			continue;
		}

		SEC_PKCS7ContentInfo *cinfo = SEC_PKCS7DecoderFinish(dc);

		if (cinfo == NULL) {
			fprintf(stderr, "Found invalid certificate\n");
			continue;
		}

		nsigs++;
		printf("---------------------------------------------\n");
		printf("Content was%s encrypted.\n",
			SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
		if (SEC_PKCS7ContentIsSigned(cinfo)) {
			char *signer_cname, *signer_ename;
			SECItem *signing_time;

			if (saw_content) {
				printf("Signature is ");
				PORT_SetError(0);
				if (SEC_PKCS7VerifySignature(cinfo,
						certUsageEmailSigner,
						PR_FALSE)) {
					printf("valid.\n");
				} else {
					printf("invalid (Reason: 0x%08x).\n",
						(uint32_t)PORT_GetError());
				}
			} else {
				printf("Content is detached; signature cannot "
					"be verified.\n");
			}

			signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
			if (signer_cname != NULL) {
				printf("The signer's common name is %s\n",
					signer_cname);
				PORT_Free(signer_cname);
			} else {
				printf("No signer common name.\n");
			}

			signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
			if (signer_ename != NULL) {
				printf("The signer's email address is %s\n",
					signer_ename);
				PORT_Free(signer_ename);
			} else {
				printf("No signer email address.\n");
			}

			signing_time = SEC_PKCS7GetSigningTime(cinfo);
			if (signing_time != NULL) {
				printf("Signing time: %s\n", DER_TimeChoiceDayToAscii(signing_time));
			} else {
				printf("No signing time included.\n");
			}

			printf("There were%s certs or crls included.\n",
				SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");

			SEC_PKCS7DestroyContentInfo(cinfo);
		}
	}
	if (nsigs) {
		printf("---------------------------------------------\n");
	} else {
		printf("No signatures found.\n");
	}
	return rc;
}
Exemple #16
0
SECStatus
SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
{
    SECStatus rv;
    SECItem **certs;
    int count;
    SECItem **rawCerts = NULL;
    PRArenaPool *arena;
    SEC_PKCS7ContentInfo *contentInfo = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
	return SECFailure;
    }

    contentInfo = SEC_PKCS7DecodeItem(certsItem, NULL, NULL, NULL, NULL, NULL, 
				      NULL, NULL);
    if ( contentInfo == NULL ) {
	goto loser;
    }

    if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) {
	goto loser;
    }


    rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
		    contentInfo->content.data);

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

    certs = rawCerts;
    if ( certs ) {
	count = 0;
	
	while ( *certs ) {
	    count++;
	    certs++;
	}
	rv = (* f)(arg, rawCerts, count);
    }
    
    rv = SECSuccess;
    
    goto done;
loser:
    rv = SECFailure;
    
done:
    if ( contentInfo ) {
	SEC_PKCS7DestroyContentInfo(contentInfo);
    }

    if ( arena ) {
	PORT_FreeArena(arena, PR_FALSE);
    }
    
    return(rv);
}