michael@0: /* michael@0: * cryptohi.h - public prototypes for the crypto library michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef _CRYPTOHI_H_ michael@0: #define _CRYPTOHI_H_ michael@0: michael@0: #include "blapit.h" michael@0: michael@0: #include "seccomon.h" michael@0: #include "secoidt.h" michael@0: #include "secdert.h" michael@0: #include "cryptoht.h" michael@0: #include "keyt.h" michael@0: #include "certt.h" michael@0: michael@0: michael@0: SEC_BEGIN_PROTOS michael@0: michael@0: michael@0: /****************************************/ michael@0: /* michael@0: ** DER encode/decode (EC)DSA signatures michael@0: */ michael@0: michael@0: /* ANSI X9.57 defines DSA signatures as DER encoded data. Our DSA1 code (and michael@0: * most of the rest of the world) just generates 40 bytes of raw data. These michael@0: * functions convert between formats. michael@0: */ michael@0: extern SECStatus DSAU_EncodeDerSig(SECItem *dest, SECItem *src); michael@0: extern SECItem *DSAU_DecodeDerSig(const SECItem *item); michael@0: michael@0: /* michael@0: * Unlike DSA1, raw DSA2 and ECDSA signatures do not have a fixed length. michael@0: * Rather they contain two integers r and s whose length depends michael@0: * on the size of q or the EC key used for signing. michael@0: * michael@0: * We can reuse the DSAU_EncodeDerSig interface to DER encode michael@0: * raw ECDSA signature keeping in mind that the length of r michael@0: * is the same as that of s and exactly half of src->len. michael@0: * michael@0: * For decoding, we need to pass the length of the desired michael@0: * raw signature (twice the key size) explicitly. michael@0: */ michael@0: extern SECStatus DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, michael@0: unsigned int len); michael@0: extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len); michael@0: michael@0: /****************************************/ michael@0: /* michael@0: ** Signature creation operations michael@0: */ michael@0: michael@0: /* michael@0: ** Create a new signature context used for signing a data stream. michael@0: ** "alg" the signature algorithm to use (e.g. SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION) michael@0: ** "privKey" the private key to use michael@0: */ michael@0: extern SGNContext *SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *privKey); michael@0: michael@0: /* michael@0: ** Destroy a signature-context object michael@0: ** "cx" the object michael@0: ** "freeit" if PR_TRUE then free the object as well as its sub-objects michael@0: */ michael@0: extern void SGN_DestroyContext(SGNContext *cx, PRBool freeit); michael@0: michael@0: /* michael@0: ** Reset the signing context "cx" to its initial state, preparing it for michael@0: ** another stream of data. michael@0: */ michael@0: extern SECStatus SGN_Begin(SGNContext *cx); michael@0: michael@0: /* michael@0: ** Update the signing context with more data to sign. michael@0: ** "cx" the context michael@0: ** "input" the input data to sign michael@0: ** "inputLen" the length of the input data michael@0: */ michael@0: extern SECStatus SGN_Update(SGNContext *cx, const unsigned char *input, michael@0: unsigned int inputLen); michael@0: michael@0: /* michael@0: ** Finish the signature process. Use either k0 or k1 to sign the data michael@0: ** stream that was input using SGN_Update. The resulting signature is michael@0: ** formatted using PKCS#1 and then encrypted using RSA private or public michael@0: ** encryption. michael@0: ** "cx" the context michael@0: ** "result" the final signature data (memory is allocated) michael@0: */ michael@0: extern SECStatus SGN_End(SGNContext *cx, SECItem *result); michael@0: michael@0: /* michael@0: ** Sign a single block of data using private key encryption and given michael@0: ** signature/hash algorithm. michael@0: ** "result" the final signature data (memory is allocated) michael@0: ** "buf" the input data to sign michael@0: ** "len" the amount of data to sign michael@0: ** "pk" the private key to encrypt with michael@0: ** "algid" the signature/hash algorithm to sign with michael@0: ** (must be compatible with the key type). michael@0: */ michael@0: extern SECStatus SEC_SignData(SECItem *result, michael@0: const unsigned char *buf, int len, michael@0: SECKEYPrivateKey *pk, SECOidTag algid); michael@0: michael@0: /* michael@0: ** Sign a pre-digested block of data using private key encryption, encoding michael@0: ** The given signature/hash algorithm. michael@0: ** "result" the final signature data (memory is allocated) michael@0: ** "digest" the digest to sign michael@0: ** "privKey" the private key to encrypt with michael@0: ** "algtag" The algorithm tag to encode (need for RSA only) michael@0: */ michael@0: extern SECStatus SGN_Digest(SECKEYPrivateKey *privKey, michael@0: SECOidTag algtag, SECItem *result, SECItem *digest); michael@0: michael@0: /* michael@0: ** DER sign a single block of data using private key encryption and the michael@0: ** MD5 hashing algorithm. This routine first computes a digital signature michael@0: ** using SEC_SignData, then wraps it with an CERTSignedData and then der michael@0: ** encodes the result. michael@0: ** "arena" is the memory arena to use to allocate data from michael@0: ** "result" the final der encoded data (memory is allocated) michael@0: ** "buf" the input data to sign michael@0: ** "len" the amount of data to sign michael@0: ** "pk" the private key to encrypt with michael@0: */ michael@0: extern SECStatus SEC_DerSignData(PLArenaPool *arena, SECItem *result, michael@0: const unsigned char *buf, int len, michael@0: SECKEYPrivateKey *pk, SECOidTag algid); michael@0: michael@0: /* michael@0: ** Destroy a signed-data object. michael@0: ** "sd" the object michael@0: ** "freeit" if PR_TRUE then free the object as well as its sub-objects michael@0: */ michael@0: extern void SEC_DestroySignedData(CERTSignedData *sd, PRBool freeit); michael@0: michael@0: /* michael@0: ** Get the signature algorithm tag number for the given key type and hash michael@0: ** algorithm tag. Returns SEC_OID_UNKNOWN if key type and hash algorithm michael@0: ** do not match or are not supported. michael@0: */ michael@0: extern SECOidTag SEC_GetSignatureAlgorithmOidTag(KeyType keyType, michael@0: SECOidTag hashAlgTag); michael@0: michael@0: /****************************************/ michael@0: /* michael@0: ** Signature verification operations michael@0: */ michael@0: michael@0: /* michael@0: ** Create a signature verification context. This version is deprecated, michael@0: ** This function is deprecated. Use VFY_CreateContextDirect or michael@0: ** VFY_CreateContextWithAlgorithmID instead. michael@0: ** "key" the public key to verify with michael@0: ** "sig" the encrypted signature data if sig is NULL then michael@0: ** VFY_EndWithSignature must be called with the correct signature at michael@0: ** the end of the processing. michael@0: ** "sigAlg" specifies the signing algorithm to use (including the michael@0: ** hash algorthim). This must match the key type. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, michael@0: SECOidTag sigAlg, void *wincx); michael@0: /* michael@0: ** Create a signature verification context. michael@0: ** "key" the public key to verify with michael@0: ** "sig" the encrypted signature data if sig is NULL then michael@0: ** VFY_EndWithSignature must be called with the correct signature at michael@0: ** the end of the processing. michael@0: ** "pubkAlg" specifies the cryptographic signing algorithm to use (the michael@0: ** raw algorithm without any hash specified. This must match the key michael@0: ** type. michael@0: ** "hashAlg" specifies the hashing algorithm used. If the key is an michael@0: ** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN. michael@0: ** the hash is selected from data in the sig. michael@0: ** "hash" optional pointer to return the actual hash algorithm used. michael@0: ** in practice this should always match the passed in hashAlg (the michael@0: ** exception is the case where hashAlg is SEC_OID_UNKNOWN above). michael@0: ** If this value is NULL no, hash oid is returned. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern VFYContext *VFY_CreateContextDirect(const SECKEYPublicKey *key, michael@0: const SECItem *sig, michael@0: SECOidTag pubkAlg, michael@0: SECOidTag hashAlg, michael@0: SECOidTag *hash, void *wincx); michael@0: /* michael@0: ** Create a signature verification context from a algorithm ID. michael@0: ** "key" the public key to verify with michael@0: ** "sig" the encrypted signature data if sig is NULL then michael@0: ** VFY_EndWithSignature must be called with the correct signature at michael@0: ** the end of the processing. michael@0: ** "algid" specifies the signing algorithm and parameters to use. michael@0: ** This must match the key type. michael@0: ** "hash" optional pointer to return the oid of the actual hash used in michael@0: ** the signature. If this value is NULL no, hash oid is returned. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern VFYContext *VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, michael@0: const SECItem *sig, michael@0: const SECAlgorithmID *algid, michael@0: SECOidTag *hash, michael@0: void *wincx); michael@0: michael@0: /* michael@0: ** Destroy a verification-context object. michael@0: ** "cx" the context to destroy michael@0: ** "freeit" if PR_TRUE then free the object as well as its sub-objects michael@0: */ michael@0: extern void VFY_DestroyContext(VFYContext *cx, PRBool freeit); michael@0: michael@0: extern SECStatus VFY_Begin(VFYContext *cx); michael@0: michael@0: /* michael@0: ** Update a verification context with more input data. The input data michael@0: ** is fed to a secure hash function (depending on what was in the michael@0: ** encrypted signature data). michael@0: ** "cx" the context michael@0: ** "input" the input data michael@0: ** "inputLen" the amount of input data michael@0: */ michael@0: extern SECStatus VFY_Update(VFYContext *cx, const unsigned char *input, michael@0: unsigned int inputLen); michael@0: michael@0: /* michael@0: ** Finish the verification process. The return value is a status which michael@0: ** indicates success or failure. On success, the SECSuccess value is michael@0: ** returned. Otherwise, SECFailure is returned and the error code found michael@0: ** using PORT_GetError() indicates what failure occurred. michael@0: ** "cx" the context michael@0: */ michael@0: extern SECStatus VFY_End(VFYContext *cx); michael@0: michael@0: /* michael@0: ** Finish the verification process. The return value is a status which michael@0: ** indicates success or failure. On success, the SECSuccess value is michael@0: ** returned. Otherwise, SECFailure is returned and the error code found michael@0: ** using PORT_GetError() indicates what failure occurred. If signature is michael@0: ** supplied the verification uses this signature to verify, otherwise the michael@0: ** signature passed in VFY_CreateContext() is used. michael@0: ** VFY_EndWithSignature(cx,NULL); is identical to VFY_End(cx);. michael@0: ** "cx" the context michael@0: ** "sig" the encrypted signature data michael@0: */ michael@0: extern SECStatus VFY_EndWithSignature(VFYContext *cx, SECItem *sig); michael@0: michael@0: michael@0: /* michael@0: ** Verify the signature on a block of data for which we already have michael@0: ** the digest. The signature data is an RSA private key encrypted michael@0: ** block of data formatted according to PKCS#1. michael@0: ** This function is deprecated. Use VFY_VerifyDigestDirect or michael@0: ** VFY_VerifyDigestWithAlgorithmID instead. michael@0: ** "dig" the digest michael@0: ** "key" the public key to check the signature with michael@0: ** "sig" the encrypted signature data michael@0: ** "sigAlg" specifies the signing algorithm to use. This must match michael@0: ** the key type. michael@0: ** "wincx" void pointer to the window context michael@0: **/ michael@0: extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key, michael@0: SECItem *sig, SECOidTag sigAlg, void *wincx); michael@0: /* michael@0: ** Verify the signature on a block of data for which we already have michael@0: ** the digest. The signature data is an RSA private key encrypted michael@0: ** block of data formatted according to PKCS#1. michael@0: ** "dig" the digest michael@0: ** "key" the public key to check the signature with michael@0: ** "sig" the encrypted signature data michael@0: ** "pubkAlg" specifies the cryptographic signing algorithm to use (the michael@0: ** raw algorithm without any hash specified. This must match the key michael@0: ** type. michael@0: ** "hashAlg" specifies the hashing algorithm used. michael@0: ** "wincx" void pointer to the window context michael@0: **/ michael@0: extern SECStatus VFY_VerifyDigestDirect(const SECItem *dig, michael@0: const SECKEYPublicKey *key, michael@0: const SECItem *sig, SECOidTag pubkAlg, michael@0: SECOidTag hashAlg, void *wincx); michael@0: /* michael@0: ** Verify the signature on a block of data for which we already have michael@0: ** the digest. The signature data is an RSA private key encrypted michael@0: ** block of data formatted according to PKCS#1. michael@0: ** "key" the public key to verify with michael@0: ** "sig" the encrypted signature data if sig is NULL then michael@0: ** VFY_EndWithSignature must be called with the correct signature at michael@0: ** the end of the processing. michael@0: ** "algid" specifies the signing algorithm and parameters to use. michael@0: ** This must match the key type. michael@0: ** "hash" oid of the actual hash used to create digest. If this value is michael@0: ** not set to SEC_OID_UNKNOWN, it must match the hash of the signature. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern SECStatus VFY_VerifyDigestWithAlgorithmID(const SECItem *dig, michael@0: const SECKEYPublicKey *key, const SECItem *sig, michael@0: const SECAlgorithmID *algid, SECOidTag hash, michael@0: void *wincx); michael@0: michael@0: /* michael@0: ** Verify the signature on a block of data. The signature data is an RSA michael@0: ** private key encrypted block of data formatted according to PKCS#1. michael@0: ** This function is deprecated. Use VFY_VerifyDataDirect or michael@0: ** VFY_VerifyDataWithAlgorithmID instead. michael@0: ** "buf" the input data michael@0: ** "len" the length of the input data michael@0: ** "key" the public key to check the signature with michael@0: ** "sig" the encrypted signature data michael@0: ** "sigAlg" specifies the signing algorithm to use. This must match michael@0: ** the key type. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern SECStatus VFY_VerifyData(const unsigned char *buf, int len, michael@0: const SECKEYPublicKey *key, const SECItem *sig, michael@0: SECOidTag sigAlg, void *wincx); michael@0: /* michael@0: ** Verify the signature on a block of data. The signature data is an RSA michael@0: ** private key encrypted block of data formatted according to PKCS#1. michael@0: ** "buf" the input data michael@0: ** "len" the length of the input data michael@0: ** "key" the public key to check the signature with michael@0: ** "sig" the encrypted signature data michael@0: ** "pubkAlg" specifies the cryptographic signing algorithm to use (the michael@0: ** raw algorithm without any hash specified. This must match the key michael@0: ** type. michael@0: ** "hashAlg" specifies the hashing algorithm used. If the key is an michael@0: ** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN. michael@0: ** the hash is selected from data in the sig. michael@0: ** "hash" optional pointer to return the actual hash algorithm used. michael@0: ** in practice this should always match the passed in hashAlg (the michael@0: ** exception is the case where hashAlg is SEC_OID_UNKNOWN above). michael@0: ** If this value is NULL no, hash oid is returned. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern SECStatus VFY_VerifyDataDirect(const unsigned char *buf, int len, michael@0: const SECKEYPublicKey *key, michael@0: const SECItem *sig, michael@0: SECOidTag pubkAlg, SECOidTag hashAlg, michael@0: SECOidTag *hash, void *wincx); michael@0: michael@0: /* michael@0: ** Verify the signature on a block of data. The signature data is an RSA michael@0: ** private key encrypted block of data formatted according to PKCS#1. michael@0: ** "buf" the input data michael@0: ** "len" the length of the input data michael@0: ** "key" the public key to check the signature with michael@0: ** "sig" the encrypted signature data michael@0: ** "algid" specifies the signing algorithm and parameters to use. michael@0: ** This must match the key type. michael@0: ** "hash" optional pointer to return the oid of the actual hash used in michael@0: ** the signature. If this value is NULL no, hash oid is returned. michael@0: ** "wincx" void pointer to the window context michael@0: */ michael@0: extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, michael@0: int len, const SECKEYPublicKey *key, michael@0: const SECItem *sig, michael@0: const SECAlgorithmID *algid, SECOidTag *hash, michael@0: void *wincx); michael@0: michael@0: michael@0: SEC_END_PROTOS michael@0: michael@0: #endif /* _CRYPTOHI_H_ */