def run(self): from sign.Sign import Sign_0_21 from LRSignature.verify.Verify import Verify_0_21 import json rawInput = self.readInput() envelopeList = self.parseInput(rawInput) if self.args.mode == "sign": self.signtool = Sign_0_21( privateKeyID=self.args.key, passphrase=self.args.passphrase, gnupgHome=self.args.gnupghome, gpgbin=self.args.gpgbin, publicKeyLocations=self.args.key_location) is_test_data_opt = self.args.lr_test_data.lower() in [ "true", "yes", "t", "y" ] signedList = self.signEnvelopes(envelopeList, is_test_data=is_test_data_opt) if self.args.publish_url != None: self.publishEnvelopes(signedList) else: print json.dumps({"documents": signedList}) elif self.args.mode == "verify": self.verifytool = Verify_0_21(gpgbin=self.args.gpgbin, gnupgHome=self.args.gnupghome) resultList = self.validateEnvelopes(envelopeList) print json.dumps({"results": resultList})
def testCorruptSignature(self): '''Test using a corrupted signature, replace the hash within a signature with a hash from a different envelope''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "baseline signing failed" # validate original with good signature verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) verified = verifytool.verify(signed) assert verified == True, "baseline validation failed" # manipulate the hash portion of a signature block altered = copy.deepcopy(unsigned) altered["X_corrupted"] = "Altered Envelope" altered_hash = signtool.get_message(altered) validHash = verifytool._extractHashFromSignature( signed["digital_signature"]["signature"]) alt_signed = copy.deepcopy(signed) alt_signed["digital_signature"]["signature"] = signed[ "digital_signature"]["signature"].replace(validHash, altered_hash) assert alt_signed["digital_signature"]["signature"] != signed[ "digital_signature"][ "signature"], "envelopes should not be equal after deliberate modificaton" verified = verifytool.verify(alt_signed) assert verified == False, "verification failed, corrupted signature block verified as good"
def testSignLRTestData(self): '''Test using LR Test Data, if available''' if self.testDataDir == None: log.info("Skipping test, test data directory not set.") return import codecs signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) allfiles = os.listdir(self.testDataDir) for root, dirs, files in os.walk(self.testDataDir): for fileName in files: log.info("Trying to sign %s" % (fileName, )) unsigned = json.load( codecs.open(os.path.join(root, fileName), "r", "utf-8-sig")) signed = signtool.sign(unsigned) assert "digital_signature" in signed, "missing digital_signature" verified = verifytool.verify(signed) assert verified == True, "baseline validation failed"
def testGetSignatureBlock(self): '''Check that signature block validation correctly returns a structurally valid response''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "envelope did not sign correctly" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) sigInfo = verifytool._getSignatureInfo(signed) assert sigInfo != None, "signature extraction from envelope failed" assert "signing_method" in sigInfo and sigInfo[ "signing_method"] == verifytool.signatureMethod, "signing_method is missing from signature block" assert "signature" in sigInfo and sigInfo["signature"] != None and len( sigInfo["signature"] ) > 0, "signature field is missing, null or is empty" assert "key_location" in sigInfo and sigInfo[ "key_location"] == self.sampleKeyLocations, "key_location field is not correct" assert "key_owner" in sigInfo and sigInfo[ "key_owner"] == signtool._get_privatekey_owner( ), "key_owner field does not match signing key"
def testWrongSignature(self): '''Test using a mis-matched signature, using a signature from a different valid envelope''' unsigned = json.loads(self.sampleJSON) altered = copy.deepcopy(unsigned) altered["X_corrupted"] = "Altered Envelope" signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signtool2 = Sign_0_21(privateKeyID=self.privateKey2.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) alt_signed = signtool2.sign(altered) assert signed != None, "original did not get signed" assert alt_signed != None, "modified copy did not get signed" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) verified = verifytool.verify(signed) assert verified == True, "signature did not verify, even though it should." verified = verifytool.verify(alt_signed) assert verified == True, "signature did not verify, even though it should." signed["digital_signature"] = alt_signed["digital_signature"] verified = verifytool.verify(signed) assert verified == False, "swapped signature block validated envelope as good."
def testBadSignatureBlockMissingNullEmptySignature(self): '''Check signature block validation with missing/null or empty signature''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "Envelope signing did not succeed correctly." verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) signed["digital_signature"]["signature"] = "" with self.assertRaises(errors.BadSignatureFormat, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.message == errors.MISSING_SIGNATURE, "Wrong exception raised" signed["digital_signature"]["signature"] = None with self.assertRaises(errors.BadSignatureFormat, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.message == errors.MISSING_SIGNATURE, "Wrong exception raised" del signed["digital_signature"]["signature"] with self.assertRaises(errors.BadSignatureFormat, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.message == errors.MISSING_SIGNATURE, "Wrong exception raised"
def validate_digital_signature(self, doc): from LRSignature.verify.Verify import Verify_0_21 from LRSignature import util from LRSignature import errors verifytool = Verify_0_21(gpgbin=gpgbin) try: verified = verifytool.verify(doc) assert verified == True, "Signature did not validate for document." except errors.MissingPublicKey: locations = doc['digital_signature']['key_location'] numImported = 0 for location in locations: rawKeys = util.fetchkeys(location) for rawKey in rawKeys: numImported += util.storekey(self.sampleKey, gpgbin=gpgbin) if numImported > 0: break assert numImported > 0, "No new public keys were imported, but were needed" try: verified = verifytool.verify(doc) assert verified == True, "Signature did not validate for document." except errors.MissingPublicKey: raise AssertionError( "No public key available that can be retrieved to validate doc" )
def testValidSignature(self): '''Check for valid signature''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "Envelope did not sign correctly" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) verified = verifytool.verify(signed) assert verified == True, "Envelope signature verification did not succeed, even though it should"
def testCorruptEnvelope(self): '''Modify a signed envelope and check for validity''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "envelope did not get signed correctly" signed["X_corrupted"] = "Corrupted Envelope" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) verified = verifytool.verify(signed) assert verified == False, "corrupted envelope verified as good"
def testBadSignatureBlockMissingLocation(self): '''Check that signature block validation correctly checks for missing key_location field''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=None) signed = signtool.sign(unsigned) assert signed != None, "Envelope not signed correctly" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) with self.assertRaises(errors.BadSignatureFormat, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.message == errors.MISSING_KEY_LOCATION, "Exception not formatted with correct message"
def testMissingPublicKey(self): '''Check for appropriate response when public key for signature is missing''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "Envelope did not sign correctly" self.gpg.delete_keys([self.privateKey.fingerprint], secret=True) self.gpg.delete_keys([self.privateKey.fingerprint], secret=False) verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) with self.assertRaises(errors.MissingPublicKey, msg="Expected exception not raised.") as caught: verified = verifytool.verify(signed) assert verified == False, "Envelope verified, despite missing public key."
def testBadSignatureBlockMissingSignatureMethod(self): '''Check signature block for missing signature_method detection''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "Envelope not signed correctly." del signed["digital_signature"]["signing_method"] verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) with self.assertRaises(errors.UnsupportedSignatureAlgorithm, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.alg == None, "Raised exception not formatted correctly"
def testBadSignatureBlockBadKeyOwner(self): '''Check signature block for a bad key_owner field''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None, "Envelope not signed correctly" signed["digital_signature"]["key_owner"] = [ "John Q. Public <*****@*****.**>" ] verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) with self.assertRaises(errors.BadSignatureFormat, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.message == errors.BAD_KEY_OWNER, "Wrong exception"
def testBadSignatureBlockBadSignatureMethod(self): '''Check signature block for detecting unsupported algorithm use''' unsigned = json.loads(self.sampleJSON) signtool = Sign_0_21(privateKeyID=self.privateKey.fingerprint, passphrase=self.genericPassphrase, gnupgHome=self.gnupgHome, gpgbin=self.gpgbin, publicKeyLocations=self.sampleKeyLocations) signed = signtool.sign(unsigned) assert signed != None signed["digital_signature"][ "signing_method"] = signtool.signatureMethod + "+BAD_SIGNATURE_METHOD" verifytool = Verify_0_21(gpgbin=self.gpgbin, gnupgHome=self.gnupgHome) with self.assertRaises(errors.UnsupportedSignatureAlgorithm, msg="Expected exception not raised.") as caught: sigInfo = verifytool._getSignatureInfo(signed) assert caught.exception.alg == signed["digital_signature"][ "signing_method"], "Exception not raised correctly."