diff --git a/enzevalos_iphone/ObjectivePGP/ObjectivePGPObject.h b/ObjectivePGP.framework/Headers/ObjectivePGPObject.h old mode 100755 new mode 100644 similarity index 98% rename from enzevalos_iphone/ObjectivePGP/ObjectivePGPObject.h rename to ObjectivePGP.framework/Headers/ObjectivePGPObject.h index 19f2383e4afc0e4ba947b5c37e57f1b222866521..0a1a923b6b818e9498e28f6c1f3996ac1d3bc1b5 --- a/enzevalos_iphone/ObjectivePGP/ObjectivePGPObject.h +++ b/ObjectivePGP.framework/Headers/ObjectivePGPObject.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPKey.h" -#import "PGPKeyring.h" +#import <ObjectivePGP/PGPKey.h> +#import <ObjectivePGP/PGPKeyring.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @@ -110,10 +110,10 @@ NS_ASSUME_NONNULL_BEGIN */ + (nullable NSArray<PGPKeyID *> *)recipientsKeyIDForMessage:(NSData *)data error:(NSError * __autoreleasing _Nullable *)error; - + (NSData*) transformKey: (NSString *) string; + (nullable NSData *)symmetricEncrypt:(NSData *)dataToEncrypt signWithKey:(nullable PGPKey *)signKey encryptionKey: (nullable NSString *) key passphrase:(nullable NSString *)passphrase armored:(BOOL)armored error:(NSError *__autoreleasing _Nullable *)error; + (nullable NSData *)symmetricDecrypt:(NSData *)messageDataToDecrypt key:(nullable NSString *)encKey verifyWithKey:(nullable PGPKey *)key signed:(nullable BOOL *)isSigned valid:(nullable BOOL *)isValid integrityProtected:(nullable BOOL *)isIntegrityProtected error:(NSError *__autoreleasing _Nullable *)error; + @end NS_ASSUME_NONNULL_END diff --git a/enzevalos_iphone/ObjectivePGP/PGPArmor.h b/ObjectivePGP.framework/Headers/PGPArmor.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPArmor.h rename to ObjectivePGP.framework/Headers/PGPArmor.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPExportableProtocol.h b/ObjectivePGP.framework/Headers/PGPExportableProtocol.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPExportableProtocol.h rename to ObjectivePGP.framework/Headers/PGPExportableProtocol.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPFingerprint.h b/ObjectivePGP.framework/Headers/PGPFingerprint.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPFingerprint.h rename to ObjectivePGP.framework/Headers/PGPFingerprint.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPKey.h b/ObjectivePGP.framework/Headers/PGPKey.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPKey.h rename to ObjectivePGP.framework/Headers/PGPKey.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPKeyGenerator.h b/ObjectivePGP.framework/Headers/PGPKeyGenerator.h old mode 100755 new mode 100644 similarity index 96% rename from enzevalos_iphone/ObjectivePGP/PGPKeyGenerator.h rename to ObjectivePGP.framework/Headers/PGPKeyGenerator.h index ebfaffd2070abc89744b4ed0c58d242d361022b1..cafd5e0a5f0a69588239d72b177802b017abc5b4 --- a/enzevalos_iphone/ObjectivePGP/PGPKeyGenerator.h +++ b/ObjectivePGP.framework/Headers/PGPKeyGenerator.h @@ -7,7 +7,7 @@ // #import <Foundation/Foundation.h> -#import "PGPTypes.h" +#import <ObjectivePGP/PGPTypes.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPKeyID.h b/ObjectivePGP.framework/Headers/PGPKeyID.h old mode 100755 new mode 100644 similarity index 91% rename from enzevalos_iphone/ObjectivePGP/PGPKeyID.h rename to ObjectivePGP.framework/Headers/PGPKeyID.h index c2c1faff4b4e9acb5f456173b6c25fb774a8cdf8..6bf4b53169149a6f9e1a2e58a2c7b3897b19338d --- a/enzevalos_iphone/ObjectivePGP/PGPKeyID.h +++ b/ObjectivePGP.framework/Headers/PGPKeyID.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPMacros.h" -#import "PGPExportableProtocol.h" +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPExportableProtocol.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPKeyring.h b/ObjectivePGP.framework/Headers/PGPKeyring.h old mode 100755 new mode 100644 similarity index 98% rename from enzevalos_iphone/ObjectivePGP/PGPKeyring.h rename to ObjectivePGP.framework/Headers/PGPKeyring.h index 3b4fc03a3bd8a53d6c10c015cb523e7469d6e4c0..228262774b93aa7069b5bbed0f0d128857315bf6 --- a/enzevalos_iphone/ObjectivePGP/PGPKeyring.h +++ b/ObjectivePGP.framework/Headers/PGPKeyring.h @@ -6,7 +6,7 @@ // This notice may not be removed from this file. // -#import "PGPKey.h" +#import <ObjectivePGP/PGPKey.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPMacros.h b/ObjectivePGP.framework/Headers/PGPMacros.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPMacros.h rename to ObjectivePGP.framework/Headers/PGPMacros.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPPartialKey.h b/ObjectivePGP.framework/Headers/PGPPartialKey.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPPartialKey.h rename to ObjectivePGP.framework/Headers/PGPPartialKey.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPPartialSubKey.h b/ObjectivePGP.framework/Headers/PGPPartialSubKey.h old mode 100755 new mode 100644 similarity index 94% rename from enzevalos_iphone/ObjectivePGP/PGPPartialSubKey.h rename to ObjectivePGP.framework/Headers/PGPPartialSubKey.h index ac0b93d6ccfade83397fe468d51f835c1c65c476..8b8ee6f4741489931f22f3ae1fee190bcaf72916 --- a/enzevalos_iphone/ObjectivePGP/PGPPartialSubKey.h +++ b/ObjectivePGP.framework/Headers/PGPPartialSubKey.h @@ -6,7 +6,7 @@ // This notice may not be removed from this file. // -#import "PGPPartialKey.h" +#import <ObjectivePGP/PGPPartialKey.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPTypes.h b/ObjectivePGP.framework/Headers/PGPTypes.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPTypes.h rename to ObjectivePGP.framework/Headers/PGPTypes.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPUser.h b/ObjectivePGP.framework/Headers/PGPUser.h old mode 100755 new mode 100644 similarity index 93% rename from enzevalos_iphone/ObjectivePGP/PGPUser.h rename to ObjectivePGP.framework/Headers/PGPUser.h index f96e66cb749ea6b0677f95ccbc6ae2265cdb8b27..60529474c0c34a910e330b4215c9b9b96e559a49 --- a/enzevalos_iphone/ObjectivePGP/PGPUser.h +++ b/ObjectivePGP.framework/Headers/PGPUser.h @@ -6,7 +6,7 @@ // This notice may not be removed from this file. // -#import "PGPMacros.h" +#import <ObjectivePGP/PGPMacros.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Utils/NSArray+PGPUtils.h b/ObjectivePGP.framework/PrivateHeaders/NSArray+PGPUtils.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Utils/NSArray+PGPUtils.h rename to ObjectivePGP.framework/PrivateHeaders/NSArray+PGPUtils.h diff --git a/enzevalos_iphone/ObjectivePGP/Utils/NSData+PGPUtils.h b/ObjectivePGP.framework/PrivateHeaders/NSData+PGPUtils.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Utils/NSData+PGPUtils.h rename to ObjectivePGP.framework/PrivateHeaders/NSData+PGPUtils.h diff --git a/enzevalos_iphone/ObjectivePGP/Utils/NSData+compression.h b/ObjectivePGP.framework/PrivateHeaders/NSData+compression.h old mode 100755 new mode 100644 similarity index 94% rename from enzevalos_iphone/ObjectivePGP/Utils/NSData+compression.h rename to ObjectivePGP.framework/PrivateHeaders/NSData+compression.h index a5c1eaffc6267a75990eca7b935db4ebc062ae1b..04ad632710d9e88be49e5e8b69af262d02a9ad1e --- a/enzevalos_iphone/ObjectivePGP/Utils/NSData+compression.h +++ b/ObjectivePGP.framework/PrivateHeaders/NSData+compression.h @@ -4,7 +4,7 @@ // rfc1950 (zlib format) #import <Foundation/Foundation.h> -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Utils/NSMutableData+PGPUtils.h b/ObjectivePGP.framework/PrivateHeaders/NSMutableData+PGPUtils.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Utils/NSMutableData+PGPUtils.h rename to ObjectivePGP.framework/PrivateHeaders/NSMutableData+PGPUtils.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPBigNum+Private.h old mode 100755 new mode 100644 similarity index 88% rename from enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPBigNum+Private.h index 3966e6b63a1a83255ab1cbb73a7bd9b05e39193d..16cc8c7f252e59e24da1450bab54613950df8102 --- a/enzevalos_iphone/ObjectivePGP/PGPBigNum+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPBigNum+Private.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPBigNum.h" -#import "PGPMacros.h" +#import <ObjectivePGP/PGPBigNum.h> +#import <ObjectivePGP/PGPMacros.h> #import <openssl/bn.h> #import <Foundation/Foundation.h> diff --git a/enzevalos_iphone/ObjectivePGP/PGPBigNum.h b/ObjectivePGP.framework/PrivateHeaders/PGPBigNum.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPBigNum.h rename to ObjectivePGP.framework/PrivateHeaders/PGPBigNum.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPCompressedPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPCompressedPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPCompressedPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPCompressedPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPCryptoCFB.h b/ObjectivePGP.framework/PrivateHeaders/PGPCryptoCFB.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPCryptoCFB.h rename to ObjectivePGP.framework/PrivateHeaders/PGPCryptoCFB.h diff --git a/enzevalos_iphone/ObjectivePGP/CryptoBox/PGPCryptoHash.h b/ObjectivePGP.framework/PrivateHeaders/PGPCryptoHash.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/CryptoBox/PGPCryptoHash.h rename to ObjectivePGP.framework/PrivateHeaders/PGPCryptoHash.h diff --git a/enzevalos_iphone/ObjectivePGP/CryptoBox/PGPCryptoUtils.h b/ObjectivePGP.framework/PrivateHeaders/PGPCryptoUtils.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/CryptoBox/PGPCryptoUtils.h rename to ObjectivePGP.framework/PrivateHeaders/PGPCryptoUtils.h diff --git a/enzevalos_iphone/ObjectivePGP/CryptoBox/PGPDSA.h b/ObjectivePGP.framework/PrivateHeaders/PGPDSA.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/CryptoBox/PGPDSA.h rename to ObjectivePGP.framework/PrivateHeaders/PGPDSA.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPEncryptedSessionKeyPacketProtocol.h b/ObjectivePGP.framework/PrivateHeaders/PGPEncryptedSessionKeyPacketProtocol.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPEncryptedSessionKeyPacketProtocol.h rename to ObjectivePGP.framework/PrivateHeaders/PGPEncryptedSessionKeyPacketProtocol.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPFoundation.h b/ObjectivePGP.framework/PrivateHeaders/PGPFoundation.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPFoundation.h rename to ObjectivePGP.framework/PrivateHeaders/PGPFoundation.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPKey+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPKey+Private.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPKey+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPKey+Private.h diff --git a/enzevalos_iphone/ObjectivePGP/CryptoBox/PGPKeyMaterial.h b/ObjectivePGP.framework/PrivateHeaders/PGPKeyMaterial.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/CryptoBox/PGPKeyMaterial.h rename to ObjectivePGP.framework/PrivateHeaders/PGPKeyMaterial.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPKeyring+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPKeyring+Private.h old mode 100755 new mode 100644 similarity index 89% rename from enzevalos_iphone/ObjectivePGP/PGPKeyring+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPKeyring+Private.h index 357ce6150ea6d6023033b583ac3b8bbf91ca91d7..f724441f2c612ff9b856ccdcd44706cec0a99b51 --- a/enzevalos_iphone/ObjectivePGP/PGPKeyring+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPKeyring+Private.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPKeyring.h" -#import "PGPKey.h" +#import <ObjectivePGP/PGPKeyring.h> +#import <ObjectivePGP/PGPKey.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPLiteralPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPLiteralPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPLiteralPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPLiteralPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPLogging.h b/ObjectivePGP.framework/PrivateHeaders/PGPLogging.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPLogging.h rename to ObjectivePGP.framework/PrivateHeaders/PGPLogging.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPMPI.h b/ObjectivePGP.framework/PrivateHeaders/PGPMPI.h old mode 100755 new mode 100644 similarity index 95% rename from enzevalos_iphone/ObjectivePGP/PGPMPI.h rename to ObjectivePGP.framework/PrivateHeaders/PGPMPI.h index 052b88f19cde1ac54b6871bdadee6fbf39c34761..b99757e8bf252a74ba99679da74f9172a007f700 --- a/enzevalos_iphone/ObjectivePGP/PGPMPI.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPMPI.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPBigNum.h" -#import "PGPMacros.h" +#import <ObjectivePGP/PGPBigNum.h> +#import <ObjectivePGP/PGPMacros.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPMacros+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPMacros+Private.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPMacros+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPMacros+Private.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPModificationDetectionCodePacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPModificationDetectionCodePacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPModificationDetectionCodePacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPModificationDetectionCodePacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPOnePassSignaturePacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPOnePassSignaturePacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPOnePassSignaturePacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPOnePassSignaturePacket.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPPKCSEme.h b/ObjectivePGP.framework/PrivateHeaders/PGPPKCSEme.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPPKCSEme.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPKCSEme.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPPKCSEmsa.h b/ObjectivePGP.framework/PrivateHeaders/PGPPKCSEmsa.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPPKCSEmsa.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPKCSEmsa.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPPacket+Private.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPacket+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPacket+Private.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPPacket.h old mode 100755 new mode 100644 similarity index 93% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPacket.h index 9c217ca0910a9ed8f52cd0d1905472ff77d85eff..4398c9de9cd75733ca084b3c6b91a13ffbe60e0d --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPPacket.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPExportableProtocol.h" -#import "PGPTypes.h" +#import <ObjectivePGP/PGPExportableProtocol.h> +#import <ObjectivePGP/PGPTypes.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPPacketFactory.h b/ObjectivePGP.framework/PrivateHeaders/PGPPacketFactory.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/PGPPacketFactory.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPacketFactory.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacketHeader.h b/ObjectivePGP.framework/PrivateHeaders/PGPPacketHeader.h old mode 100755 new mode 100644 similarity index 97% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPacketHeader.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPacketHeader.h index f1cc536b2af6059f03dad0d114f39893292f8b7b..6f91dbf1f7eaefcb9a10f62d6a568dd94e840fc1 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPacketHeader.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPPacketHeader.h @@ -6,7 +6,7 @@ // #import <Foundation/Foundation.h> -#import "PGPTypes.h" +#import <ObjectivePGP/PGPTypes.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPPartialSubKey+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPPartialSubKey+Private.h old mode 100755 new mode 100644 similarity index 90% rename from enzevalos_iphone/ObjectivePGP/PGPPartialSubKey+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPartialSubKey+Private.h index 472c5ebaa82feedcd3082bba0b2f58a82201ccae..6e4ec3d25a01bc892094a15fda24d3d25c272326 --- a/enzevalos_iphone/ObjectivePGP/PGPPartialSubKey+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPPartialSubKey+Private.h @@ -6,7 +6,7 @@ // This notice may not be removed from this file. // -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> @interface PGPPartialSubKey () diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyEncryptedSessionKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyEncryptedSessionKeyPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyEncryptedSessionKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyEncryptedSessionKeyPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket+Private.h old mode 100755 new mode 100644 similarity index 94% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket+Private.h index 3900aa01b1bbfd3f006db7744d5d7cc8c0c65f8e..d6b2d35c6307eebf0aa50a06d17250b585a7cadd --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket+Private.h @@ -7,7 +7,7 @@ // #import "PGPPublicKeyPacket.h" -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket.h old mode 100755 new mode 100644 similarity index 96% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket.h index 12740c1f540ff5237b93d16a1811e2001c03cf2a..cf199de62b8ded991b76973a44ad52a637f65f36 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicKeyPacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPPublicKeyPacket.h @@ -8,7 +8,7 @@ // Tag 6 #import "PGPPacketFactory.h" -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicSubKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPPublicSubKeyPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPPublicSubKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPPublicSubKeyPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/CryptoBox/PGPRSA.h b/ObjectivePGP.framework/PrivateHeaders/PGPRSA.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/CryptoBox/PGPRSA.h rename to ObjectivePGP.framework/PrivateHeaders/PGPRSA.h diff --git a/enzevalos_iphone/ObjectivePGP/PGPS2K.h b/ObjectivePGP.framework/PrivateHeaders/PGPS2K.h old mode 100755 new mode 100644 similarity index 91% rename from enzevalos_iphone/ObjectivePGP/PGPS2K.h rename to ObjectivePGP.framework/PrivateHeaders/PGPS2K.h index 15c3d9bac1d6451113b52e64936e7a778a2270cf..7f3c2f0d24335dae7170f71593d028f764742e83 --- a/enzevalos_iphone/ObjectivePGP/PGPS2K.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPS2K.h @@ -6,9 +6,9 @@ // This notice may not be removed from this file. // -#import "PGPMacros.h" -#import "PGPTypes.h" -#import "PGPExportableProtocol.h" +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPTypes.h> +#import <ObjectivePGP/PGPExportableProtocol.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPSecretKeyPacket+Private.h old mode 100755 new mode 100644 similarity index 95% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSecretKeyPacket+Private.h index 246a367df4ed1565e6a856fdff251558f17b84a1..7aca638f41fd5f2a8ef26081e07c84b6a3bcc2e8 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPSecretKeyPacket+Private.h @@ -9,7 +9,7 @@ #import "PGPPublicKeyPacket+Private.h" #import "PGPS2K.h" #import "PGPSecretKeyPacket.h" -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSecretKeyPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSecretKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSecretKeyPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSecretSubKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSecretSubKeyPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSecretSubKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSecretSubKeyPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignaturePacket+Private.h old mode 100755 new mode 100644 similarity index 96% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignaturePacket+Private.h index 88610992080d0aa82ba43470a4ef18c53103d391..9c17602c7d84a3801fcc498b12dde1672ff093c6 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket+Private.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPSignaturePacket+Private.h @@ -7,7 +7,7 @@ // #import "PGPSignaturePacket.h" -#import "ObjectivePGP.h" +#import <ObjectivePGP/ObjectivePGP.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignaturePacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignaturePacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignaturePacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacket+Private.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacket+Private.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacket+Private.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacket+Private.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacket.h old mode 100755 new mode 100644 similarity index 91% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacket.h index 36da084e079280e2ef3fd9c0948c70f60c5330dc..8f6149ca826dc315b0d9f3bc68cccf7197bf8310 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacket.h @@ -6,9 +6,9 @@ // This notice may not be removed from this file. // -#import "PGPTypes.h" -#import "PGPMacros.h" -#import "PGPExportableProtocol.h" +#import <ObjectivePGP/PGPTypes.h> +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPExportableProtocol.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketCreationTime.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketCreationTime.h old mode 100755 new mode 100644 similarity index 86% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketCreationTime.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketCreationTime.h index ca8e9c6c6d78828f2c44534cba32cd8c0bec12ed..1dea1529aed3e510903b2176e5f33bb81c7821a2 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketCreationTime.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketCreationTime.h @@ -8,9 +8,9 @@ // 5.2.3.4. Signature Creation Time // Signature Creation Time MUST be present in the hashed area. -#import "PGPTypes.h" -#import "PGPMacros.h" -#import "PGPExportableProtocol.h" +#import <ObjectivePGP/PGPTypes.h> +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPExportableProtocol.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketEmbeddedSignature.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketEmbeddedSignature.h old mode 100755 new mode 100644 similarity index 80% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketEmbeddedSignature.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketEmbeddedSignature.h index a16fdd2fcb83e71d35643c37ec0155c77a1979e4..6bb44de581acecc8c2fe803b42544a3933d7d436 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketEmbeddedSignature.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketEmbeddedSignature.h @@ -6,10 +6,10 @@ // // 5.2.3.26. Embedded Signature -#import "PGPTypes.h" -#import "PGPMacros.h" -#import "PGPExportableProtocol.h" -#import "PGPSignatureSubpacket.h" +#import <ObjectivePGP/PGPTypes.h> +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPExportableProtocol.h> +#import <ObjectivePGP/PGPSignatureSubpacket.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketHeader.h b/ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketHeader.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSignatureSubpacketHeader.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSignatureSubpacketHeader.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSymetricKeyEncryptedSessionKeyPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSymetricKeyEncryptedSessionKeyPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSymetricKeyEncryptedSessionKeyPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSymetricKeyEncryptedSessionKeyPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSymmetricallyEncryptedDataPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSymmetricallyEncryptedDataPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSymmetricallyEncryptedDataPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSymmetricallyEncryptedDataPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPSymmetricallyEncryptedIntegrityProtectedDataPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPSymmetricallyEncryptedIntegrityProtectedDataPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPSymmetricallyEncryptedIntegrityProtectedDataPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPSymmetricallyEncryptedIntegrityProtectedDataPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPTrustPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPTrustPacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPTrustPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPTrustPacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributeImageSubpacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPUserAttributeImageSubpacket.h old mode 100755 new mode 100644 similarity index 90% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributeImageSubpacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPUserAttributeImageSubpacket.h index a0302942f87813edef9405aabb012332b24faae7..3abe24d2480a38e348403ffcb60a00138c815b04 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributeImageSubpacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPUserAttributeImageSubpacket.h @@ -5,7 +5,7 @@ // This notice may not be removed from this file. // -#import "ObjectivePGP-Private.h" +#import <ObjectivePGP/ObjectivePGP-Private.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributePacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPUserAttributePacket.h old mode 100755 new mode 100644 similarity index 84% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributePacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPUserAttributePacket.h index e014e9522c40665cf0a4bcdfe01728151e6bcbe8..820bd7407c2ea5f226b3e7ab9d5f2d71f68e1e45 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributePacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPUserAttributePacket.h @@ -6,8 +6,8 @@ // This notice may not be removed from this file. // -#import "PGPUserAttributeSubpacket.h" -#import "PGPPacket.h" +#import <ObjectivePGP/PGPUserAttributeSubpacket.h> +#import <ObjectivePGP/PGPPacket.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributeSubpacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPUserAttributeSubpacket.h old mode 100755 new mode 100644 similarity index 100% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPUserAttributeSubpacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPUserAttributeSubpacket.h diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserIDPacket.h b/ObjectivePGP.framework/PrivateHeaders/PGPUserIDPacket.h old mode 100755 new mode 100644 similarity index 89% rename from enzevalos_iphone/ObjectivePGP/Packets/PGPUserIDPacket.h rename to ObjectivePGP.framework/PrivateHeaders/PGPUserIDPacket.h index d7fe2926a00a1e54be4e9032702064a7890d4ca9..67ea33d23303cae16f22b874255d79e93985afdb --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPUserIDPacket.h +++ b/ObjectivePGP.framework/PrivateHeaders/PGPUserIDPacket.h @@ -7,8 +7,8 @@ // // Tag 13 -#import "PGPMacros.h" -#import "PGPPacket.h" +#import <ObjectivePGP/PGPMacros.h> +#import <ObjectivePGP/PGPPacket.h> #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN diff --git a/enzevalos_iphone/ObjectivePGP/PGPPartialKey+Private.h b/enzevalos_iphone/ObjectivePGP/PGPPartialKey+Private.h deleted file mode 100755 index 742005390f1b67061587556d5d4a5f514f113381..0000000000000000000000000000000000000000 --- a/enzevalos_iphone/ObjectivePGP/PGPPartialKey+Private.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright (c) Marcin Krzyżanowski. All rights reserved. -// -// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY -// INTERNATIONAL COPYRIGHT LAW. USAGE IS BOUND TO THE LICENSE AGREEMENT. -// This notice may not be removed from this file. -// - -#import "ObjectivePGP.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface PGPPartialKey () - -@property (nonatomic, readwrite) PGPKeyType type; -@property (nonatomic, copy, readwrite) NSArray<PGPPartialSubKey *> *subKeys; -@property (nonatomic, copy, readwrite) NSArray<PGPSignaturePacket *> *directSignatures; -@property (nonatomic, nullable, copy, readwrite) PGPSignaturePacket *revocationSignature; - -- (void)loadPackets:(NSArray<PGPPacket *> *)packets NS_REQUIRES_SUPER; - -@end - -NS_ASSUME_NONNULL_END diff --git a/enzevalos_iphone/ObjectivePGP/PGPUser+Private.h b/enzevalos_iphone/ObjectivePGP/PGPUser+Private.h deleted file mode 100755 index 50401068cd3425ef15655d9724c20165aefae30f..0000000000000000000000000000000000000000 --- a/enzevalos_iphone/ObjectivePGP/PGPUser+Private.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Marcin Krzyżanowski. All rights reserved. -// -// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY -// INTERNATIONAL COPYRIGHT LAW. USAGE IS BOUND TO THE LICENSE AGREEMENT. -// This notice may not be removed from this file. -// - -#import "ObjectivePGP.h" -#import "PGPUserIDPacket.h" -#import "PGPUserAttributePacket.h" -#import "PGPSignaturePacket.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface PGPUser () - -@property (nonatomic, copy) NSArray<PGPSignaturePacket *> *selfCertifications; -@property (nonatomic, copy) NSArray<PGPSignaturePacket *> *otherSignatures; -@property (nonatomic, copy) NSArray<PGPSignaturePacket *> *revocationSignatures; - -@property (nonatomic, copy, nullable) PGPUserAttributePacket *userAttribute; -@property (nonatomic, copy, readonly) PGPUserIDPacket *userIDPacket; - -@property (nonatomic, readonly) NSArray<PGPPacket *> *allPackets; - -- (instancetype)initWithUserIDPacket:(PGPUserIDPacket *)userPacket NS_DESIGNATED_INITIALIZER; - -- (nullable PGPSignaturePacket *)validSelfCertificate; - -@end - -NS_ASSUME_NONNULL_END diff --git a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicSubKeyPacket.m b/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicSubKeyPacket.m deleted file mode 100755 index 48d2ed03ee21d3fb178e052a57f5fdcf7028a7c8..0000000000000000000000000000000000000000 --- a/enzevalos_iphone/ObjectivePGP/Packets/PGPPublicSubKeyPacket.m +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (c) Marcin Krzyżanowski. All rights reserved. -// -// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY -// INTERNATIONAL COPYRIGHT LAW. USAGE IS BOUND TO THE LICENSE AGREEMENT. -// This notice may not be removed from this file. -// - -#import "PGPPublicSubKeyPacket.h" - -@implementation PGPPublicSubKeyPacket - -- (PGPPacketTag)tag { - return PGPPublicSubkeyPacketTag; -} - -@end diff --git a/netpgp/PGPKeyGeneration.swift b/netpgp/PGPKeyGeneration.swift deleted file mode 100644 index b95d4bb698271d3e1d75cf47d0ff49183e81d4cd..0000000000000000000000000000000000000000 --- a/netpgp/PGPKeyGeneration.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// PGPKeyGeneration.swift -// enzevalos_iphone -// -// Created by Oliver Wiese on 10.06.17. -// Copyright © 2017 fu-berlin. All rights reserved. -// - -import Foundation - - -public func createKey(userID:String){ - var adr: UInt8 - adr = 8 - var pk: Array<CChar> = Array(repeating: 32, count: 4048) - //var sk: Array<CChar> = Array(repeating: 32, count: 4048) - - var sk: pgp_key_t = generateSecretKey(&adr) - - print("CreateKey") - mre2ee_driver_create_keypair(&adr, &pk, &pk) - - - print("###########") - - - -} - - - - diff --git a/netpgp/autocryptgen.c b/netpgp/autocryptgen.c deleted file mode 100644 index 600c890a66b8101a1178235739375b9a43ed6e36..0000000000000000000000000000000000000000 --- a/netpgp/autocryptgen.c +++ /dev/null @@ -1,294 +0,0 @@ -// -// autocryptgen.c -// enzevalos_iphone -// -// Created by Oliver Wiese on 11.06.17. -// Copyright © 2017 fu-berlin. All rights reserved. -// - -#include "autocryptgen.h" - -pgp_key_t -generateSecretKey(uint8_t* adr) -{ - pgp_key_t seckey; - uint8_t* user_id = NULL; - - memset(&seckey, 0, sizeof(pgp_key_t)); - user_id = adr; - /* generate two keypairs */ - pgp_rsa_generate_keypair(&seckey, 2048/*bits*/, 65537UL/*e*/, NULL, NULL, NULL, 0); - return seckey; - -} - - -char * -netpgp2_strdup(const char *s) -{ - size_t len; - char *cp; - - len = strlen(s); - if ((cp = calloc(1, len + 1)) != NULL) { - (void) memcpy(cp, s, len); - cp[len] = 0x0; - } - return cp; -} - - -char * -pgp_export_my_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase) -{ - pgp_output_t *output; - pgp_memory_t *mem; - char *cp; - - pgp_setup_memory_write(&output, &mem, 128); - pgp_write_xfer_key(output, keydata, 1); - - /* TODO deal with passphrase again - pgp_write_xfer_seckey(output, keydata, passphrase, - strlen((char *)passphrase), 1); - */ - cp = netpgp2_strdup(pgp_mem_data(mem)); - pgp_teardown_memory_write(output, mem); - printf("CP: %s \n",cp); - return cp; -} - - -/******************************************************************************* - * Key generatation - ******************************************************************************/ - - -static unsigned add_key_prefs(pgp_create_sig_t *sig) -{ - /* similar to pgp_add_key_prefs(), Mimic of GPG default settings, limited to supported algos */ - return - /* Symmetric algo prefs */ - pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_SKA) && - pgp_write_scalar(sig->output, PGP_SA_AES_256, 1) && - pgp_write_scalar(sig->output, PGP_SA_AES_128, 1) && - pgp_write_scalar(sig->output, PGP_SA_CAST5, 1) && - pgp_write_scalar(sig->output, PGP_SA_TRIPLEDES, 1) && - pgp_write_scalar(sig->output, PGP_SA_IDEA, 1) && - - /* Hash algo prefs, the first algo is the preferred algo */ - pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_HASH) && - pgp_write_scalar(sig->output, PGP_HASH_SHA256, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA384, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA512, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA224, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA1, 1) && /* Edit for Autocrypt/Delta Chat: due to the weak SHA1, it should not be preferred */ - - /* Compression algo prefs */ - pgp_write_ss_header(sig->output, 2/*1+number of following items*/, PGP_PTAG_SS_PREF_COMPRESS) && - pgp_write_scalar(sig->output, PGP_C_ZLIB, 1) /*&& -- not sure if Delta Chat will support bzip2 on all platforms, however, this is not that important as typical files are compressed themselves and text is not that big - pgp_write_scalar(sig->output, PGP_C_BZIP2, 1) -- if you re-enable this, do not forget to modifiy the header count*/; -} - - -static void add_selfsigned_userid(pgp_key_t *skey, pgp_key_t *pkey, const uint8_t *userid, time_t key_expiry) -{ - /* similar to pgp_add_selfsigned_userid() which, however, uses different key flags */ - pgp_create_sig_t *sig; - pgp_subpacket_t sigpacket; - pgp_memory_t *mem_sig = NULL; - pgp_output_t *sigoutput = NULL; - - /* create sig for this pkt */ - sig = pgp_create_sig_new(); - pgp_sig_start_key_sig(sig, &skey->key.seckey.pubkey, NULL, userid, PGP_CERT_POSITIVE); - - pgp_add_creation_time(sig, time(NULL)); - pgp_add_key_expiration_time(sig, key_expiry); - pgp_add_primary_userid(sig, 1); - pgp_add_key_flags(sig, PGP_KEYFLAG_SIGN_DATA|PGP_KEYFLAG_CERT_KEYS); - add_key_prefs(sig); - pgp_add_key_features(sig); /* will add 0x01 - modification detection */ - - pgp_end_hashed_subpkts(sig); - - pgp_add_issuer_keyid(sig, skey->pubkeyid); /* the issuer keyid is not hashed by definition */ - - pgp_setup_memory_write(&sigoutput, &mem_sig, 128); - pgp_write_sig(sigoutput, sig, &skey->key.seckey.pubkey, &skey->key.seckey); - - /* add this packet to key */ - sigpacket.length = pgp_mem_len(mem_sig); - sigpacket.raw = pgp_mem_data(mem_sig); - - /* add user id and signature to key */ - pgp_update_userid(skey, userid, &sigpacket, &sig->sig.info); - if(pkey) { - pgp_update_userid(pkey, userid, &sigpacket, &sig->sig.info); - } - - /* cleanup */ - pgp_create_sig_delete(sig); - pgp_output_delete(sigoutput); - pgp_memory_free(mem_sig); -} - - -static void add_subkey_binding_signature(pgp_subkeysig_t* p, pgp_key_t* primarykey, pgp_key_t* subkey, pgp_key_t* seckey) -{ - /*add "0x18: Subkey Binding Signature" packet, PGP_SIG_SUBKEY */ - pgp_create_sig_t* sig; - pgp_output_t* sigoutput = NULL; - pgp_memory_t* mem_sig = NULL; - - sig = pgp_create_sig_new(); - pgp_sig_start_key_sig(sig, &primarykey->key.pubkey, &subkey->key.pubkey, NULL, PGP_SIG_SUBKEY); - - pgp_add_creation_time(sig, time(NULL)); - pgp_add_key_expiration_time(sig, 0); - pgp_add_key_flags(sig, PGP_KEYFLAG_ENC_STORAGE|PGP_KEYFLAG_ENC_COMM); /* NB: algo/hash/compression preferences are not added to subkeys */ - - pgp_end_hashed_subpkts(sig); - - pgp_add_issuer_keyid(sig, seckey->pubkeyid); /* the issuer keyid is not hashed by definition */ - - pgp_setup_memory_write(&sigoutput, &mem_sig, 128); - pgp_write_sig(sigoutput, sig, &seckey->key.seckey.pubkey, &seckey->key.seckey); - - p->subkey = primarykey->subkeyc-1; /* index of subkey in array */ - p->packet.length = mem_sig->length; - p->packet.raw = mem_sig->buf; mem_sig->buf = NULL; /* move ownership to packet */ - copy_sig_info(&p->siginfo, &sig->sig.info); /* not sure, if this is okay, however, siginfo should be set up, otherwise we get "bad info-type" errors */ - - pgp_create_sig_delete(sig); - pgp_output_delete(sigoutput); - free(mem_sig); /* do not use pgp_memory_free() as this would also free mem_sig->buf which is owned by the packet */ -} - - -int mre2ee_driver_create_keypair(uint8_t* adr, char* pk, char* sk)//const char* addr) -{ - int success = 0; - pgp_key_t seckey, pubkey, subkey; - uint8_t subkeyid[PGP_KEY_ID_SIZE]; - uint8_t* user_id = NULL; - pgp_memory_t *pubmem = pgp_memory_new(), *secmem = pgp_memory_new(); - pgp_output_t *pubout = pgp_output_new(), *secout = pgp_output_new(); - - memset(&seckey, 0, sizeof(pgp_key_t)); - memset(&pubkey, 0, sizeof(pgp_key_t)); - memset(&subkey, 0, sizeof(pgp_key_t)); - - if( //addr==NULL || - pubmem==NULL || secmem==NULL || pubout==NULL || secout==NULL ) { - goto cleanup; - } - - /* Generate User ID. For convention, use the same address as given in `Autocrypt: to=...` in angle brackets - (RFC 2822 grammar angle-addr, see also https://autocrypt.org/en/latest/level0.html#type-p-openpgp-based-key-data ) - We do not add the name to the ID for the following reasons: - - privacy - - the name may be changed - - shorter keys - - the name is already taken from From: - - not Autocrypt:-standard */ - //user_id = 0; //addr// (uint8_t*) mr_mprintf("<%s>", addr); // (uint8_t)atoi - user_id = adr; - /* generate two keypairs */ - if( !pgp_rsa_generate_keypair(&seckey, 2048/*bits*/, 65537UL/*e*/, NULL, NULL, NULL, 0) - || !pgp_rsa_generate_keypair(&subkey, 2048/*bits*/, 65537UL/*e*/, NULL, NULL, NULL, 0) ) { - goto cleanup; - } - - - /* Create public key, bind public subkey to public key - ------------------------------------------------------------------------ */ - - pubkey.type = PGP_PTAG_CT_PUBLIC_KEY; - pgp_pubkey_dup(&pubkey.key.pubkey, &seckey.key.pubkey); - memcpy(pubkey.pubkeyid, seckey.pubkeyid, PGP_KEY_ID_SIZE); - pgp_fingerprint(&pubkey.pubkeyfpr, &seckey.key.pubkey, 0); - add_selfsigned_userid(&seckey, &pubkey, (const uint8_t*)user_id, 0/*never expire*/); - - EXPAND_ARRAY((&pubkey), subkey); - { - pgp_subkey_t* p = &pubkey.subkeys[pubkey.subkeyc++]; - pgp_pubkey_dup(&p->key.pubkey, &subkey.key.pubkey); - pgp_keyid(subkeyid, PGP_KEY_ID_SIZE, &pubkey.key.pubkey, PGP_HASH_SHA1); - memcpy(p->id, subkeyid, PGP_KEY_ID_SIZE); - } - - EXPAND_ARRAY((&pubkey), subkeysig); - add_subkey_binding_signature(&pubkey.subkeysigs[pubkey.subkeysigc++], &pubkey, &subkey, &seckey); - - - /* Create secret key, bind secret subkey to secret key - ------------------------------------------------------------------------ */ - - EXPAND_ARRAY((&seckey), subkey); - { - pgp_subkey_t* p = &seckey.subkeys[seckey.subkeyc++]; - pgp_seckey_dup(&p->key.seckey, &subkey.key.seckey); - pgp_keyid(subkeyid, PGP_KEY_ID_SIZE, &seckey.key.pubkey, PGP_HASH_SHA1); - memcpy(p->id, subkeyid, PGP_KEY_ID_SIZE); - } - - EXPAND_ARRAY((&seckey), subkeysig); - add_subkey_binding_signature(&seckey.subkeysigs[seckey.subkeysigc++], &seckey, &subkey, &seckey); - - - /* Done with key generation, write binary keys to memory - ------------------------------------------------------------------------ */ - - printf("Write in mem \n"); - - pgp_writer_set_memory(pubout, pubmem); - if( !pgp_write_xfer_key(pubout, &pubkey, 1/*armored*/) - || pubmem->buf == NULL || pubmem->length <= 0 ) { - goto cleanup; - } - - pgp_writer_set_memory(secout, secmem); - if( !pgp_write_xfer_key(secout, &seckey, 1/*armored*/) - || secmem->buf == NULL || secmem->length <= 0 ) { - goto cleanup; - } - - - - //pgp_filewrite(pk, pubmem->buf, pubmem->length, 1); - //pgp_filewrite(sk, secmem->buf, secmem->length, 1); - - - printf("\n My key??? %s \n",pgp_mem_data(pubmem)); - - pgp_io_t s_io; - - memset(&s_io, 0, sizeof(pgp_io_t)); - s_io.outs = stdout; - s_io.errs = stdout; - s_io.res = stdout; - - // memcpy(pk, pubout, pubmem->length); - // memcpy(sk, secout, secmem->length); - printf("before export\n"); - sk = pgp_export_my_key(&s_io, &pubkey, NULL); - printf("after export\n"); - - - - - success = 1; - -cleanup: - if( pubout ) { pgp_output_delete(pubout); } - if( secout ) { pgp_output_delete(secout); } - if( pubmem ) { pgp_memory_free(pubmem); } - if( secmem ) { pgp_memory_free(secmem); } - pgp_key_free(&seckey); /* not: pgp_keydata_free() which will also free the pointer itself (we created it on the stack) */ - pgp_key_free(&pubkey); - pgp_key_free(&subkey); - //free(user_id); - return success; -} - diff --git a/netpgp/autocryptgen.h b/netpgp/autocryptgen.h deleted file mode 100644 index 00e318394fa5d4d5d1e6e7e224f1b2527d25240a..0000000000000000000000000000000000000000 --- a/netpgp/autocryptgen.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// autocryptgen.h -// enzevalos_iphone -// -// Created by Oliver Wiese on 11.06.17. -// Copyright © 2017 fu-berlin. All rights reserved. -// - -#ifndef autocryptgen_h -#define autocryptgen_h - -#include <stdio.h> -#include "netpgp-extra.h" - - -int mre2ee_driver_create_keypair(uint8_t* adr, char* pk, char* sk);//const char* addr); -pgp_key_t generateSecretKey(uint8_t* adr); - -#endif /* autocryptgen_h */ diff --git a/netpgp/compress.c b/netpgp/compress.c deleted file mode 100644 index 3186a019af52371dd7c8a788c37c7f30ef1a2745..0000000000000000000000000000000000000000 --- a/netpgp/compress.c +++ /dev/null @@ -1,490 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#ifdef HAVE_ZLIB_H -#include <zlib.h> -#endif - -#ifdef HAVE_BZLIB_H -#include <bzlib.h> -#endif - -#include <string.h> - -#include "netpgp/packet-parse.h" -#include "netpgp/errors.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/crypto.h" -#include "netpgp/memory.h" -#include "netpgp/writer.h" - -#define DECOMPRESS_BUFFER 1024 - -typedef struct { - pgp_compression_type_t type; - pgp_region_t *region; - uint8_t in[DECOMPRESS_BUFFER]; - uint8_t out[DECOMPRESS_BUFFER]; - z_stream zstream;/* ZIP and ZLIB */ - size_t offset; - int inflate_ret; -} z_decompress_t; - -#ifdef HAVE_BZLIB_H -typedef struct { - pgp_compression_type_t type; - pgp_region_t *region; - char in[DECOMPRESS_BUFFER]; - char out[DECOMPRESS_BUFFER]; - bz_stream bzstream; /* BZIP2 */ - size_t offset; - int inflate_ret; -} bz_decompress_t; -#endif - -typedef struct { - z_stream stream; - uint8_t *src; - uint8_t *dst; -} compress_t; - -/* - * \todo re move code duplication between this and - * bzip2_compressed_data_reader - */ -static int -zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - z_decompress_t *z = pgp_reader_get_arg(readinfo); - size_t len; - size_t cc; - char *cdest = dest; - - if (z->type != PGP_C_ZIP && z->type != PGP_C_ZLIB) { - (void) fprintf(stderr, - "zlib_compressed_data_reader: weird type %d\n", - z->type); - return 0; - } - - if (z->inflate_ret == Z_STREAM_END && - z->zstream.next_out == &z->out[z->offset]) { - return 0; - } - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, - "zlib_compressed_data_reader: length %" PRIsize "d\n", - length); - } - for (cc = 0 ; cc < length ; cc += len) { - if (&z->out[z->offset] == z->zstream.next_out) { - int ret; - - z->zstream.next_out = z->out; - z->zstream.avail_out = sizeof(z->out); - z->offset = 0; - if (z->zstream.avail_in == 0) { - unsigned n = z->region->length; - - if (!z->region->indeterminate) { - n -= z->region->readc; - if (n > sizeof(z->in)) { - n = sizeof(z->in); - } - } else { - n = sizeof(z->in); - } - if (!pgp_stacked_limited_read(stream, z->in, n, - z->region, - errors, readinfo, cbinfo)) { - return -1; - } - - z->zstream.next_in = z->in; - z->zstream.avail_in = (z->region->indeterminate) ? - z->region->last_read : n; - } - ret = inflate(&z->zstream, Z_SYNC_FLUSH); - if (ret == Z_STREAM_END) { - if (!z->region->indeterminate && - z->region->readc != z->region->length) { - PGP_ERROR_1(cbinfo->errors, - PGP_E_P_DECOMPRESSION_ERROR, - "%s", - "Compressed stream ended before packet end."); - } - } else if (ret != Z_OK) { - (void) fprintf(stderr, "ret=%d\n", ret); - PGP_ERROR_1(cbinfo->errors, - PGP_E_P_DECOMPRESSION_ERROR, "%s", - z->zstream.msg); - } - z->inflate_ret = ret; - } - if (z->zstream.next_out <= &z->out[z->offset]) { - (void) fprintf(stderr, "Out of memory in buffer\n"); - return 0; - } - len = (size_t)(z->zstream.next_out - &z->out[z->offset]); - size_t left_in_cdest = length - cc; - if (len > left_in_cdest) { - len = left_in_cdest; - } - (void) memcpy(&cdest[cc], &z->out[z->offset], len); - z->offset += len; - } - - return (int)length; -} - -#ifdef HAVE_BZLIB_H -/* \todo remove code duplication between this and zlib_compressed_data_reader */ -static int -bzip2_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - bz_decompress_t *bz = pgp_reader_get_arg(readinfo); - size_t len; - size_t cc; - char *cdest = dest; - - if (bz->type != PGP_C_BZIP2) { - (void) fprintf(stderr, "Weird type %d\n", bz->type); - return 0; - } - if (bz->inflate_ret == BZ_STREAM_END && - bz->bzstream.next_out == &bz->out[bz->offset]) { - return 0; - } - for (cc = 0 ; cc < length ; cc += len) { - if (&bz->out[bz->offset] == bz->bzstream.next_out) { - int ret; - - bz->bzstream.next_out = (char *) bz->out; - bz->bzstream.avail_out = sizeof(bz->out); - bz->offset = 0; - if (bz->bzstream.avail_in == 0) { - unsigned n = bz->region->length; - - if (!bz->region->indeterminate) { - n -= bz->region->readc; - if (n > sizeof(bz->in)) - n = sizeof(bz->in); - } else - n = sizeof(bz->in); - - if (!pgp_stacked_limited_read(stream, - (uint8_t *) bz->in, - n, bz->region, - errors, readinfo, cbinfo)) - return -1; - - bz->bzstream.next_in = bz->in; - bz->bzstream.avail_in = - (bz->region->indeterminate) ? - bz->region->last_read : n; - } - ret = BZ2_bzDecompress(&bz->bzstream); - if (ret == BZ_STREAM_END) { - if (!bz->region->indeterminate && - bz->region->readc != bz->region->length) - PGP_ERROR_1(cbinfo->errors, - PGP_E_P_DECOMPRESSION_ERROR, - "%s", - "Compressed stream ended before packet end."); - } else if (ret != BZ_OK) { - PGP_ERROR_1(cbinfo->errors, - PGP_E_P_DECOMPRESSION_ERROR, - "Invalid return %d from BZ2_bzDecompress", ret); - } - bz->inflate_ret = ret; - } - if (bz->bzstream.next_out <= &bz->out[bz->offset]) { - (void) fprintf(stderr, "Out of bz memroy\n"); - return 0; - } - len = (size_t)(bz->bzstream.next_out - &bz->out[bz->offset]); - if (len > length) { - len = length; - } - (void) memcpy(&cdest[cc], &bz->out[bz->offset], len); - bz->offset += len; - } - - return (int)length; -} -#endif - -/** - * \ingroup Core_Compress - * - * \param *region Pointer to a region - * \param *stream How to parse - * \param type Which compression type to expect -*/ - -int -pgp_decompress(pgp_region_t *region, pgp_stream_t *stream, - pgp_compression_type_t type) -{ - z_decompress_t z; -#ifdef HAVE_BZLIB_H - bz_decompress_t bz; -#endif - const int printerrors = 1; - int ret; - - switch (type) { - case PGP_C_ZIP: - case PGP_C_ZLIB: - (void) memset(&z, 0x0, sizeof(z)); - - z.region = region; - z.offset = 0; - z.type = type; - - z.zstream.next_in = Z_NULL; - z.zstream.avail_in = 0; - z.zstream.next_out = z.out; - z.zstream.zalloc = Z_NULL; - z.zstream.zfree = Z_NULL; - z.zstream.opaque = Z_NULL; - - break; - -#ifdef HAVE_BZLIB_H - case PGP_C_BZIP2: - (void) memset(&bz, 0x0, sizeof(bz)); - - bz.region = region; - bz.offset = 0; - bz.type = type; - - bz.bzstream.next_in = NULL; - bz.bzstream.avail_in = 0; - bz.bzstream.next_out = bz.out; - bz.bzstream.bzalloc = NULL; - bz.bzstream.bzfree = NULL; - bz.bzstream.opaque = NULL; -#endif - - break; - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - switch (type) { - case PGP_C_ZIP: - /* LINTED */ /* this is a lint problem in zlib.h header */ - ret = (int)inflateInit2(&z.zstream, -15); - break; - - case PGP_C_ZLIB: - /* LINTED */ /* this is a lint problem in zlib.h header */ - ret = (int)inflateInit(&z.zstream); - break; - -#ifdef HAVE_BZLIB_H - case PGP_C_BZIP2: - ret = BZ2_bzDecompressInit(&bz.bzstream, 1, 0); - break; -#endif - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - switch (type) { - case PGP_C_ZIP: - case PGP_C_ZLIB: - if (ret != Z_OK) { - PGP_ERROR_1(&stream->errors, - PGP_E_P_DECOMPRESSION_ERROR, -"Cannot initialise ZIP or ZLIB stream for decompression: error=%d", ret); - return 0; - } - pgp_reader_push(stream, zlib_compressed_data_reader, - NULL, &z); - break; - -#ifdef HAVE_BZLIB_H - case PGP_C_BZIP2: - if (ret != BZ_OK) { - PGP_ERROR_1(&stream->errors, - PGP_E_P_DECOMPRESSION_ERROR, -"Cannot initialise BZIP2 stream for decompression: error=%d", ret); - return 0; - } - pgp_reader_push(stream, bzip2_compressed_data_reader, - NULL, &bz); - break; -#endif - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - ret = pgp_parse(stream, !printerrors); - - pgp_reader_pop(stream); - - return ret; -} - -/** -\ingroup Core_WritePackets -\brief Writes Compressed packet -\param data Data to write out -\param len Length of data -\param output Write settings -\return 1 if OK; else 0 -*/ - -unsigned -pgp_writez(pgp_output_t *out, const uint8_t *data, const unsigned len) -{ - compress_t *zip; - size_t sz_in; - size_t sz_out; - int ret; - int r = 0; - - /* compress the data */ - const int level = Z_DEFAULT_COMPRESSION; /* \todo allow varying - * levels */ - - if ((zip = calloc(1, sizeof(*zip))) == NULL) { - (void) fprintf(stderr, "pgp_writez: bad alloc\n"); - return 0; - } - zip->stream.zalloc = Z_NULL; - zip->stream.zfree = Z_NULL; - zip->stream.opaque = NULL; - - /* all other fields set to zero by use of calloc */ - - /* LINTED */ /* this is a lint problem in zlib.h header */ - if ((int)deflateInit(&zip->stream, level) != Z_OK) { - (void) fprintf(stderr, "pgp_writez: can't initialise\n"); - return 0; - } - /* do necessary transformation */ - /* copy input to maintain const'ness of src */ - if (zip->src != NULL || zip->dst != NULL) { - (void) fprintf(stderr, "pgp_writez: non-null streams\n"); - return 0; - } - - sz_in = len * sizeof(uint8_t); - sz_out = ((101 * sz_in) / 100) + 12; /* from zlib webpage */ - if ((zip->src = calloc(1, sz_in)) == NULL) { - free(zip); - (void) fprintf(stderr, "pgp_writez: bad alloc2\n"); - return 0; - } - if ((zip->dst = calloc(1, sz_out)) == NULL) { - free(zip->src); - free(zip); - (void) fprintf(stderr, "pgp_writez: bad alloc3\n"); - return 0; - } - (void) memcpy(zip->src, data, len); - - /* setup stream */ - zip->stream.next_in = zip->src; - zip->stream.avail_in = (unsigned)sz_in; - zip->stream.total_in = 0; - - zip->stream.next_out = zip->dst; - zip->stream.avail_out = (unsigned)sz_out; - zip->stream.total_out = 0; - - do { - r = deflate(&zip->stream, Z_FINISH); - } while (r != Z_STREAM_END); - - /* write it out */ - ret = pgp_write_ptag(out, PGP_PTAG_CT_COMPRESSED) && - pgp_write_length(out, (unsigned)(zip->stream.total_out + 1))&& - pgp_write_scalar(out, PGP_C_ZLIB, 1) && - pgp_write(out, zip->dst, (unsigned)zip->stream.total_out); - - free(zip->src); - free(zip->dst); - free(zip); - return ret; -} diff --git a/netpgp/create.c b/netpgp/create.c deleted file mode 100644 index a15a0e5863659df73fd3a6db2fae2512110317b1..0000000000000000000000000000000000000000 --- a/netpgp/create.c +++ /dev/null @@ -1,1376 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_OPENSSL_CAST_H -#include <openssl/cast.h> -#endif - -#include "netpgp/create.h" -#include "netpgp/keyring.h" -#include "netpgp/packet.h" -#include "netpgp/signature.h" -#include "netpgp/writer.h" -#include "netpgp/readerwriter.h" -#include "netpgp/memory.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/netpgpdigest.h" - -/** - * \ingroup Core_Create - * \param length - * \param type - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_ss_header(pgp_output_t *output, - size_t length, - pgp_content_enum type) -{ - return pgp_write_length(output, (unsigned int)length) && - pgp_write_scalar(output, (unsigned)(type - - (unsigned)PGP_PTAG_SIG_SUBPKT_BASE), 1); -} - -/* - * XXX: the general idea of _fast_ is that it doesn't copy stuff the safe - * (i.e. non _fast_) version will, and so will also need to be freed. - */ - -/** - * \ingroup Core_Create - * - * pgp_fast_create_userid() sets id->userid to the given userid. - * This is fast because it is only copying a char*. However, if userid - * is changed or freed in the future, this could have injurious results. - * \param id - * \param userid - */ - -void -pgp_fast_create_userid(uint8_t **id, uint8_t *userid) -{ - *id = userid; -} - -/** - * \ingroup Core_WritePackets - * \brief Writes a User Id packet - * \param id - * \param output - * \return 1 if OK, otherwise 0 - */ -unsigned -pgp_write_struct_userid(pgp_output_t *output, const uint8_t *id) -{ - return pgp_write_ptag(output, PGP_PTAG_CT_USER_ID) && - pgp_write_length(output, (unsigned)strlen((const char *) id)) && - pgp_write(output, id, (unsigned)strlen((const char *) id)); -} - -/** - * \ingroup Core_WritePackets - * \brief Write a User Id packet. - * \param userid - * \param output - * - * \return return value from pgp_write_struct_userid() - */ -unsigned -pgp_write_userid(const uint8_t *userid, pgp_output_t *output) -{ - return pgp_write_struct_userid(output, userid); -} - -/** -\ingroup Core_MPI -*/ -static unsigned -mpi_length(const BIGNUM *bn) -{ - return (unsigned)(2 + (BN_num_bits(bn) + 7) / 8); -} - -static unsigned -pubkey_length(const pgp_pubkey_t *key) -{ - switch (key->alg) { - case PGP_PKA_DSA: - return mpi_length(key->key.dsa.p) + mpi_length(key->key.dsa.q) + - mpi_length(key->key.dsa.g) + mpi_length(key->key.dsa.y); - - case PGP_PKA_RSA: - return mpi_length(key->key.rsa.n) + mpi_length(key->key.rsa.e); - - case PGP_PKA_ELGAMAL: - return mpi_length(key->key.elgamal.p) + - mpi_length(key->key.elgamal.g) + - mpi_length(key->key.elgamal.y); - - default: - (void) fprintf(stderr, - "pubkey_length: unknown key algorithm\n"); - } - return 0; -} - -static unsigned -seckey_length(const pgp_seckey_t *key) -{ - int len; - - switch (key->pubkey.alg) { - case PGP_PKA_DSA: - return (unsigned)(mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey)); - case PGP_PKA_RSA: - len = mpi_length(key->key.rsa.d) + mpi_length(key->key.rsa.p) + - mpi_length(key->key.rsa.q) + mpi_length(key->key.rsa.u); - - return (unsigned)(len + pubkey_length(&key->pubkey)); - - case PGP_PKA_ELGAMAL: - return (unsigned)( - mpi_length(key->key.dsa.x) + pubkey_length(&key->pubkey)); - - default: - (void) fprintf(stderr, - "seckey_length: unknown key algorithm\n"); - } - return 0; -} - -/** - * \ingroup Core_Create - * \param key - * \param t - * \param n - * \param e -*/ -void -pgp_fast_create_rsa_pubkey(pgp_pubkey_t *key, time_t t, - BIGNUM *n, BIGNUM *e) -{ - key->version = PGP_V4; - key->birthtime = t; - key->alg = PGP_PKA_RSA; - key->key.rsa.n = n; - key->key.rsa.e = e; -} - -/* - * Note that we support v3 keys here because they're needed for for - * verification - the writer doesn't allow them, though - */ -static unsigned -write_pubkey_body(const pgp_pubkey_t *key, pgp_output_t *output) -{ - if (!(pgp_write_scalar(output, (unsigned)key->version, 1) && - pgp_write_scalar(output, (unsigned)key->birthtime, 4))) { - return 0; - } - - if (key->version != 4 && - !pgp_write_scalar(output, key->days_valid, 2)) { - return 0; - } - - if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) { - return 0; - } - - switch (key->alg) { - case PGP_PKA_DSA: - return pgp_write_mpi(output, key->key.dsa.p) && - pgp_write_mpi(output, key->key.dsa.q) && - pgp_write_mpi(output, key->key.dsa.g) && - pgp_write_mpi(output, key->key.dsa.y); - - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - return pgp_write_mpi(output, key->key.rsa.n) && - pgp_write_mpi(output, key->key.rsa.e); - - case PGP_PKA_ELGAMAL: - return pgp_write_mpi(output, key->key.elgamal.p) && - pgp_write_mpi(output, key->key.elgamal.g) && - pgp_write_mpi(output, key->key.elgamal.y); - - default: - (void) fprintf(stderr, - "write_pubkey_body: bad algorithm\n"); - break; - } - return 0; -} - -/* - * Note that we support v3 keys here because they're needed for - * verification. - */ -static unsigned -write_seckey_body(const pgp_seckey_t *key, - const uint8_t *passphrase, - const size_t pplen, - pgp_output_t *output) -{ - /* RFC4880 Section 5.5.3 Secret-Key Packet Formats */ - - pgp_crypt_t crypted; - pgp_hash_t hash; - unsigned done = 0; - unsigned i = 0; - uint8_t sesskey[CAST_KEY_LENGTH]; - - if (!write_pubkey_body(&key->pubkey, output)) { - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->s2k_usage, 1)) { - return 0; - } - if (key->s2k_usage != PGP_S2KU_NONE) { - if (key->s2k_usage != PGP_S2KU_ENCRYPTED_AND_HASHED) { - (void) fprintf(stderr, "write_seckey_body: s2k usage\n"); - return 0; - } - - if (key->alg != PGP_SA_CAST5) { - (void) fprintf(stderr, "write_seckey_body: algorithm\n"); - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->alg, 1)) { - return 0; - } - - if (key->s2k_specifier != PGP_S2KS_SIMPLE && - key->s2k_specifier != PGP_S2KS_SALTED) { - /* = 1 \todo could also be iterated-and-salted */ - (void) fprintf(stderr, "write_seckey_body: s2k spec\n"); - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->s2k_specifier, 1)) { - return 0; - } - if (!pgp_write_scalar(output, (unsigned)key->hash_alg, 1)) { - return 0; - } - - switch (key->s2k_specifier) { - case PGP_S2KS_SIMPLE: - /* nothing more to do */ - break; - - case PGP_S2KS_SALTED: - /* 8-octet salt value */ - pgp_random(__UNCONST(&key->salt[0]), PGP_SALT_SIZE); - if (!pgp_write(output, key->salt, PGP_SALT_SIZE)) { - return 0; - } - break; - - /* - * \todo case PGP_S2KS_ITERATED_AND_SALTED: // 8-octet salt - * value // 1-octet count break; - */ - - default: - (void) fprintf(stderr, - "invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - return 0; - } - - if (!pgp_write(output, &key->iv[0], pgp_block_size(key->alg))) { - return 0; - } - - /* - * create the session key for encrypting the algorithm-specific - * fields - */ - - switch (key->s2k_specifier) { - case PGP_S2KS_SIMPLE: - case PGP_S2KS_SALTED: - /* RFC4880: section 3.7.1.1 and 3.7.1.2 */ - - for (done = 0, i = 0; done < CAST_KEY_LENGTH; i++) { - unsigned hashsize; - unsigned j; - unsigned needed; - unsigned size; - uint8_t zero = 0; - uint8_t *hashed; - - /* Hard-coded SHA1 for session key */ - pgp_hash_any(&hash, PGP_HASH_SHA1); - hashsize = pgp_hash_size(key->hash_alg); - needed = CAST_KEY_LENGTH - done; - size = MIN(needed, hashsize); - if ((hashed = calloc(1, hashsize)) == NULL) { - (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); - return 0; - } - if (!hash.init(&hash)) { - (void) fprintf(stderr, "write_seckey_body: bad alloc\n"); - free(hashed); - return 0; - } - - /* preload if iterating */ - for (j = 0; j < i; j++) { - /* - * Coverity shows a DEADCODE error on this - * line. This is expected since the hardcoded - * use of SHA1 and CAST5 means that it will - * not used. This will change however when - * other algorithms are supported. - */ - hash.add(&hash, &zero, 1); - } - - if (key->s2k_specifier == PGP_S2KS_SALTED) { - hash.add(&hash, key->salt, PGP_SALT_SIZE); - } - hash.add(&hash, passphrase, (unsigned)pplen); - hash.finish(&hash, hashed); - - /* - * if more in hash than is needed by session key, use - * the leftmost octets - */ - (void) memcpy(&sesskey[i * hashsize], - hashed, (unsigned)size); - done += (unsigned)size; - free(hashed); - if (done > CAST_KEY_LENGTH) { - (void) fprintf(stderr, - "write_seckey_body: short add\n"); - return 0; - } - } - - break; - - /* - * \todo case PGP_S2KS_ITERATED_AND_SALTED: * 8-octet salt - * value * 1-octet count break; - */ - - default: - (void) fprintf(stderr, - "invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - return 0; - } - - /* use this session key to encrypt */ - - pgp_crypt_any(&crypted, key->alg); - crypted.set_iv(&crypted, key->iv); - crypted.set_crypt_key(&crypted, sesskey); - pgp_encrypt_init(&crypted); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "writing: iv=", key->iv, pgp_block_size(key->alg)); - hexdump(stderr, "key= ", sesskey, CAST_KEY_LENGTH); - (void) fprintf(stderr, "\nturning encryption on...\n"); - } - pgp_push_enc_crypt(output, &crypted); - }else{ - pgp_push_sum16_writer(output); - } - - switch (key->pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (!pgp_write_mpi(output, key->key.rsa.d) || - !pgp_write_mpi(output, key->key.rsa.p) || - !pgp_write_mpi(output, key->key.rsa.q) || - !pgp_write_mpi(output, key->key.rsa.u)) { - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, - "4 x mpi not written - problem\n"); - } - return 0; - } - break; - case PGP_PKA_DSA: - return pgp_write_mpi(output, key->key.dsa.x); - case PGP_PKA_ELGAMAL: - return pgp_write_mpi(output, key->key.elgamal.x); - default: - return 0; - } - - - if (key->s2k_usage != PGP_S2KU_NONE) { - - if (!pgp_write(output, key->checkhash, PGP_CHECKHASH_SIZE)) { - return 0; - } - pgp_writer_pop(output); - }else{ - uint16_t checksum = pgp_pop_sum16_writer(output); - if (!pgp_write_scalar(output, checksum, 2)) { - return 0; - } - } - - return 1; -} - -/** - * \ingroup Core_WritePackets - * \brief Writes a Public Key packet - * \param key - * \param output - * \return 1 if OK, otherwise 0 - */ -unsigned -pgp_write_struct_pubkey_ptag( - pgp_output_t *output, - const pgp_pubkey_t *key, - pgp_content_enum ptag) -{ - return pgp_write_ptag(output, ptag) && - pgp_write_length(output, 1 + 4 + 1 + pubkey_length(key)) && - write_pubkey_body(key, output); -} -unsigned -pgp_write_struct_pubkey(pgp_output_t *output, const pgp_pubkey_t *key) -{ - return pgp_write_struct_pubkey_ptag(output, key, PGP_PTAG_CT_PUBLIC_KEY); -} - -/** - \ingroup HighLevel_KeyWrite - - \brief Writes a transferable PGP public key to the given output stream. - - \param keydata Key to be written - \param armoured Flag is set for armoured output - \param output Output stream - -*/ - -unsigned -pgp_write_xfer_key(pgp_output_t *output, - const pgp_key_t *key, - const unsigned armoured) -{ - unsigned directsigidx = 0; - pgp_directsig_t *directsigp; - unsigned uididx = 0; - unsigned uidsigidx = 0; - uint8_t **uidp; - pgp_uidsig_t *uidsigp; - pgp_subkey_t *subkeyp; - unsigned subkeyidx = 0; - unsigned subkeysigidx = 0; - pgp_subkeysig_t *subkeysigp; - - #if 0 ////// -- we don't need armored keys, EDIT BY MR - if (armoured) { - pgp_writer_push_armoured(output, PGP_PGP_PUBLIC_KEY_BLOCK); - } - #endif ////// - - /* primary key */ - if (key->type == PGP_PTAG_CT_PUBLIC_KEY) { - if (!pgp_write_struct_pubkey(output, &key->key.pubkey)) { - return 0; - } - }else{ - if (!pgp_write_struct_seckey(&key->key.seckey, (const uint8_t *)"", 0, output)) { - return 0; - } - } - - directsigp = key->directsigs; - for (directsigidx = 0 ; directsigidx < key->directsigc; - directsigidx++, directsigp++) - { - if (!pgp_write(output, directsigp->packet.raw, - (unsigned)directsigp->packet.length)) { - return 0; - } - } - - /* Loop over key's user ids*/ - uidp = key->uids; - for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++) - { - if (!pgp_write_struct_userid(output, *uidp)) { - return 0; - } - /* Loop over key's user ids sigs */ - uidsigp = key->uidsigs; - for (uidsigidx = 0 ; uidsigidx < key->uidsigc; uidsigidx++, uidsigp++) - { - /* matching selected user id */ - if(uidsigp->uid == uididx) - { - if (!pgp_write(output, uidsigp->packet.raw, - (unsigned)uidsigp->packet.length)) { - return 0; - } - } - } - } - - /* TODO attibutes */ - - /* Loop over key's subkeys */ - subkeyp = key->subkeys; - for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++) - { - if (key->type == PGP_PTAG_CT_PUBLIC_KEY) { - if (!pgp_write_struct_pubkey_ptag( - output, &subkeyp->key.pubkey, - PGP_PTAG_CT_PUBLIC_SUBKEY)) { - return 0; - } - }else{ - if (!pgp_write_struct_seckey_ptag( - /* TODO support passphrase again */ - &subkeyp->key.seckey, (const uint8_t *)"", 0, output, - PGP_PTAG_CT_SECRET_SUBKEY)) { - return 0; - } - } - - /* Loop over key's subkeys sigs */ - subkeysigp = key->subkeysigs; - for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc; - subkeysigidx++, subkeysigp++) - { - /* matching selected subkey */ - if(subkeysigp->subkey == subkeyidx) - { - if (!pgp_write(output, subkeysigp->packet.raw, - (unsigned)subkeysigp->packet.length)) { - return 0; - } - } - } - } - - if (armoured) { - pgp_writer_info_finalise(&output->errors, &output->writer); - pgp_writer_pop(output); - } - return 1; -} - -/** - \ingroup HighLevel_KeyWrite - - \brief Writes a transferable PGP secret key to the given output stream. - - \param keydata Key to be written - \param passphrase - \param pplen - \param armoured Flag is set for armoured output - \param output Output stream - -*/ -/* TODO have encrypted key export again -unsigned -pgp_write_xfer_seckey(pgp_output_t *output, - const pgp_key_t *key, - const uint8_t *passphrase, - const size_t pplen, - unsigned armoured) -*/ - -/** - * \ingroup Core_WritePackets - * \brief Writes one RSA public key packet. - * \param t Creation time - * \param n RSA public modulus - * \param e RSA public encryption exponent - * \param output Writer settings - * - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_rsa_pubkey(time_t t, const BIGNUM *n, - const BIGNUM *e, - pgp_output_t *output) -{ - pgp_pubkey_t key; - - pgp_fast_create_rsa_pubkey(&key, t, __UNCONST(n), __UNCONST(e)); - return pgp_write_struct_pubkey(output, &key); -} - -/** - * \ingroup Core_Create - * \param out - * \param key - * \param make_packet - */ - -void -pgp_build_pubkey(pgp_memory_t *out, const pgp_pubkey_t *key, - unsigned make_packet) -{ - pgp_output_t *output; - - output = pgp_output_new(); - pgp_memory_init(out, 128); - pgp_writer_set_memory(output, out); - write_pubkey_body(key, output); - if (make_packet) { - pgp_memory_make_packet(out, PGP_PTAG_CT_PUBLIC_KEY); - } - pgp_output_delete(output); -} - -/** - * \ingroup Core_Create - * - * Create an RSA secret key structure. If a parameter is marked as - * [OPTIONAL], then it can be omitted and will be calculated from - * other params - or, in the case of e, will default to 0x10001. - * - * Parameters are _not_ copied, so will be freed if the structure is - * freed. - * - * \param key The key structure to be initialised. - * \param t - * \param d The RSA parameter d (=e^-1 mod (p-1)(q-1)) [OPTIONAL] - * \param p The RSA parameter p - * \param q The RSA parameter q (q > p) - * \param u The RSA parameter u (=p^-1 mod q) [OPTIONAL] - * \param n The RSA public parameter n (=p*q) [OPTIONAL] - * \param e The RSA public parameter e */ - -void -pgp_fast_create_rsa_seckey(pgp_seckey_t *key, time_t t, - BIGNUM *d, BIGNUM *p, BIGNUM *q, BIGNUM *u, - BIGNUM *n, BIGNUM *e) -{ - pgp_fast_create_rsa_pubkey(&key->pubkey, t, n, e); - - /* XXX: calculate optionals */ - key->key.rsa.d = d; - key->key.rsa.p = p; - key->key.rsa.q = q; - key->key.rsa.u = u; - - key->s2k_usage = PGP_S2KU_NONE; - - /* XXX: sanity check and add errors... */ -} - -/** - * \ingroup Core_WritePackets - * \brief Writes a Secret Key packet. - * \param key The secret key - * \param passphrase The passphrase - * \param pplen Length of passphrase - * \param output - * \return 1 if OK; else 0 - */ -unsigned -pgp_write_struct_seckey_ptag(const pgp_seckey_t *key, - const uint8_t *passphrase, - const size_t pplen, - pgp_output_t *output, - pgp_content_enum ptag) -{ - int length = 0; - - if (key->pubkey.version != 4) { - (void) fprintf(stderr, - "pgp_write_struct_seckey: public key version\n"); - return 0; - } - - /* Ref: RFC4880 Section 5.5.3 */ - - /* pubkey, excluding MPIs */ - length += 1 + 4 + 1; - - /* s2k usage */ - length += 1; - - switch (key->s2k_usage) { - case PGP_S2KU_NONE: - /* nothing to add */ - break; - - case PGP_S2KU_ENCRYPTED_AND_HASHED: /* 254 */ - case PGP_S2KU_ENCRYPTED: /* 255 */ - - /* Ref: RFC4880 Section 3.7 */ - length += 1; /* s2k_specifier */ - - switch (key->s2k_specifier) { - case PGP_S2KS_SIMPLE: - length += 1; /* hash algorithm */ - break; - - case PGP_S2KS_SALTED: - length += 1 + 8; /* hash algorithm + salt */ - break; - - case PGP_S2KS_ITERATED_AND_SALTED: - length += 1 + 8 + 1; /* hash algorithm, salt + - * count */ - break; - - default: - (void) fprintf(stderr, - "pgp_write_struct_seckey: s2k spec\n"); - return 0; - } - break; - - default: - (void) fprintf(stderr, - "pgp_write_struct_seckey: s2k usage\n"); - return 0; - } - - /* IV */ - if (key->s2k_usage) { - length += pgp_block_size(key->alg); - } - /* checksum or hash */ - switch (key->s2k_usage) { - case PGP_S2KU_NONE: - case PGP_S2KU_ENCRYPTED: - length += 2; - break; - - case PGP_S2KU_ENCRYPTED_AND_HASHED: - length += PGP_CHECKHASH_SIZE; - break; - - default: - (void) fprintf(stderr, - "pgp_write_struct_seckey: s2k cksum usage\n"); - return 0; - } - - /* secret key and public key MPIs */ - length += (unsigned)seckey_length(key); - - return pgp_write_ptag(output, ptag) && - /* pgp_write_length(output,1+4+1+1+seckey_length(key)+2) && */ - pgp_write_length(output, (unsigned)length) && - write_seckey_body(key, passphrase, pplen, output); -} - -unsigned -pgp_write_struct_seckey(const pgp_seckey_t *key, - const uint8_t *passphrase, - const size_t pplen, - pgp_output_t *output) -{ - return pgp_write_struct_seckey_ptag( - key, passphrase, pplen, output, PGP_PTAG_CT_SECRET_KEY); -} -/** - * \ingroup Core_Create - * - * \brief Create a new pgp_output_t structure. - * - * \return the new structure. - * \note It is the responsiblity of the caller to call pgp_output_delete(). - * \sa pgp_output_delete() - */ -pgp_output_t * -pgp_output_new(void) -{ - return calloc(1, sizeof(pgp_output_t)); -} - -/** - * \ingroup Core_Create - * \brief Delete an pgp_output_t strucut and associated resources. - * - * Delete an pgp_output_t structure. If a writer is active, then - * that is also deleted. - * - * \param info the structure to be deleted. - */ -void -pgp_output_delete(pgp_output_t *output) -{ - pgp_writer_info_delete(&output->writer); - free(output); -} - -/** - \ingroup Core_Create - \brief Calculate the checksum for a session key - \param sesskey Session Key to use - \param cs Checksum to be written - \return 1 if OK; else 0 -*/ -unsigned -pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *sesskey, uint8_t cs[2]) -{ - uint32_t checksum = 0; - unsigned i; - - if (!pgp_is_sa_supported(sesskey->symm_alg)) { - return 0; - } - - for (i = 0; i < pgp_key_size(sesskey->symm_alg); i++) { - checksum += sesskey->key[i]; - } - checksum = checksum % 65536; - - cs[0] = (uint8_t)((checksum >> 8) & 0xff); - cs[1] = (uint8_t)(checksum & 0xff); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "nm buf checksum:", cs, 2); - } - return 1; -} - -static unsigned -create_unencoded_m_buf(pgp_pk_sesskey_t *sesskey, pgp_crypt_t *cipherinfo, uint8_t *m_buf) -{ - unsigned i; - - /* m_buf is the buffer which will be encoded in PKCS#1 block - * encoding to form the "m" value used in the Public Key - * Encrypted Session Key Packet as defined in RFC Section 5.1 - * "Public-Key Encrypted Session Key Packet" - */ - m_buf[0] = sesskey->symm_alg; - for (i = 0; i < cipherinfo->keysize ; i++) { - /* XXX - Flexelint - Warning 679: Suspicious Truncation in arithmetic expression combining with pointer */ - m_buf[1 + i] = sesskey->key[i]; - } - - return pgp_calc_sesskey_checksum(sesskey, - m_buf + 1 + cipherinfo->keysize); -} - -/** -\ingroup Core_Create -\brief implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC -\param M -\param mLen -\param pubkey -\param EM -\return 1 if OK; else 0 -*/ -unsigned -encode_m_buf(const uint8_t *M, size_t mLen, const pgp_pubkey_t * pubkey, - uint8_t *EM) -{ - unsigned k; - unsigned i; - - /* implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC */ - switch (pubkey->alg) { - case PGP_PKA_RSA: - k = (unsigned)BN_num_bytes(pubkey->key.rsa.n); - if (mLen > k - 11) { - (void) fprintf(stderr, "encode_m_buf: message too long\n"); - return 0; - } - break; - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - k = (unsigned)BN_num_bytes(pubkey->key.elgamal.p); - if (mLen > k - 11) { - (void) fprintf(stderr, "encode_m_buf: message too long\n"); - return 0; - } - break; - default: - (void) fprintf(stderr, "encode_m_buf: pubkey algorithm\n"); - return 0; - } - /* these two bytes defined by RFC */ - EM[0] = 0x00; - EM[1] = 0x02; - /* add non-zero random bytes of length k - mLen -3 */ - for (i = 2; i < (k - mLen) - 1; ++i) { - do { - pgp_random(EM + i, 1); - } while (EM[i] == 0); - } - if (i < 8 + 2) { - (void) fprintf(stderr, "encode_m_buf: bad i len\n"); - return 0; - } - EM[i++] = 0; - (void) memcpy(EM + i, M, mLen); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "Encoded Message:", EM, mLen); - } - return 1; -} - -/** - \ingroup Core_Create -\brief Creates an pgp_pk_sesskey_t struct from keydata -\param key Keydata to use -\return pgp_pk_sesskey_t struct -\note It is the caller's responsiblity to free the returned pointer -\note Currently hard-coded to use CAST5 -\note Currently hard-coded to use RSA -*/ -pgp_pk_sesskey_t * -pgp_create_pk_sesskey(pgp_key_t *key, const char *ciphername, pgp_pk_sesskey_t *initial_sesskey) -{ - /* - * Creates a random session key and encrypts it for the given key - * - * Encryption used is PK, - * can be any, we're hardcoding RSA for now - */ - - pgp_pubkey_t *pubkey; - pgp_pk_sesskey_t *sesskey; - pgp_symm_alg_t cipher; - const uint8_t *id; - pgp_crypt_t cipherinfo; - uint8_t *unencoded_m_buf; - uint8_t *encoded_m_buf; - size_t sz_encoded_m_buf; - - pubkey = pgp_key_get_enckey(key, &id); - if( pubkey == NULL ) { // avoid crashes if the key cannot encode, EDIT BY MR (bp) - return NULL; - } - - /* allocate unencoded_m_buf here */ - (void) memset(&cipherinfo, 0x0, sizeof(cipherinfo)); - pgp_crypt_any(&cipherinfo, - cipher = pgp_str_to_cipher((ciphername) ? ciphername : "cast5")); - unencoded_m_buf = calloc(1, cipherinfo.keysize + 1 + 2); - if (unencoded_m_buf == NULL) { - (void) fprintf(stderr, - "pgp_create_pk_sesskey: can't allocate\n"); - return NULL; - } - switch(pubkey->alg) { - case PGP_PKA_RSA: - sz_encoded_m_buf = BN_num_bytes(pubkey->key.rsa.n); - break; - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - sz_encoded_m_buf = BN_num_bytes(pubkey->key.elgamal.p); - break; - default: - sz_encoded_m_buf = 0; - break; - } - if ((encoded_m_buf = calloc(1, sz_encoded_m_buf)) == NULL) { - (void) fprintf(stderr, - "pgp_create_pk_sesskey: can't allocate\n"); - free(unencoded_m_buf); - return NULL; - } - if ((sesskey = calloc(1, sizeof(*sesskey))) == NULL) { - (void) fprintf(stderr, - "pgp_create_pk_sesskey: can't allocate\n"); - free(unencoded_m_buf); - free(encoded_m_buf); - return NULL; - } - if (key->type != PGP_PTAG_CT_PUBLIC_KEY) { - (void) fprintf(stderr, - "pgp_create_pk_sesskey: bad type\n"); - free(unencoded_m_buf); - free(encoded_m_buf); - free(sesskey); - return NULL; - } - sesskey->version = PGP_PKSK_V3; - (void) memcpy(sesskey->key_id, id, sizeof(sesskey->key_id)); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "Encrypting for keyid", id, sizeof(sesskey->key_id)); - } - switch (pubkey->alg) { - case PGP_PKA_RSA: - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - break; - default: - (void) fprintf(stderr, - "pgp_create_pk_sesskey: bad pubkey algorithm\n"); - free(unencoded_m_buf); - free(encoded_m_buf); - free(sesskey); - return NULL; - } - sesskey->alg = pubkey->alg; - - sesskey->symm_alg = cipher; - if(initial_sesskey){ - if(initial_sesskey->symm_alg != cipher){ - return NULL; - } - memcpy(sesskey->key, initial_sesskey->key, cipherinfo.keysize); - }else{ - pgp_random(sesskey->key, cipherinfo.keysize); - } - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sesskey created", sesskey->key, - cipherinfo.keysize + 1 + 2); - } - if (create_unencoded_m_buf(sesskey, &cipherinfo, &unencoded_m_buf[0]) == 0) { - free(unencoded_m_buf); - free(encoded_m_buf); - free(sesskey); - return NULL; - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "uuencoded m buf", unencoded_m_buf, cipherinfo.keysize + 1 + 2); - } - encode_m_buf(unencoded_m_buf, cipherinfo.keysize + 1 + 2, pubkey, encoded_m_buf); - - /* and encrypt it */ - switch (key->key.pubkey.alg) { - case PGP_PKA_RSA: - if (!pgp_rsa_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey, - &sesskey->params)) { - free(unencoded_m_buf); - free(encoded_m_buf); - free(sesskey); - return NULL; - } - break; - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - if (!pgp_elgamal_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey, - &sesskey->params)) { - free(unencoded_m_buf); - free(encoded_m_buf); - free(sesskey); - return NULL; - } - break; - default: - /* will not get here - for lint only */ - break; - } - free(unencoded_m_buf); - free(encoded_m_buf); - return sesskey; -} - -/** -\ingroup Core_WritePackets -\brief Writes Public Key Session Key packet -\param info Write settings -\param pksk Public Key Session Key to write out -\return 1 if OK; else 0 -*/ -unsigned -pgp_write_pk_sesskey(pgp_output_t *output, pgp_pk_sesskey_t *pksk) -{ - /* XXX - Flexelint - Pointer parameter 'pksk' (line 1076) could be declared as pointing to const */ - if (pksk == NULL) { - (void) fprintf(stderr, - "pgp_write_pk_sesskey: NULL pksk\n"); - return 0; - } - switch (pksk->alg) { - case PGP_PKA_RSA: - return pgp_write_ptag(output, PGP_PTAG_CT_PK_SESSION_KEY) && - pgp_write_length(output, (unsigned)(1 + 8 + 1 + - BN_num_bytes(pksk->params.rsa.encrypted_m) + 2)) && - pgp_write_scalar(output, (unsigned)pksk->version, 1) && - pgp_write(output, pksk->key_id, 8) && - pgp_write_scalar(output, (unsigned)pksk->alg, 1) && - pgp_write_mpi(output, pksk->params.rsa.encrypted_m) - /* ?? && pgp_write_scalar(output, 0, 2); */ - ; - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - return pgp_write_ptag(output, PGP_PTAG_CT_PK_SESSION_KEY) && - pgp_write_length(output, (unsigned)(1 + 8 + 1 + - BN_num_bytes(pksk->params.elgamal.g_to_k) + 2 + - BN_num_bytes(pksk->params.elgamal.encrypted_m) + 2)) && - pgp_write_scalar(output, (unsigned)pksk->version, 1) && - pgp_write(output, pksk->key_id, 8) && - pgp_write_scalar(output, (unsigned)pksk->alg, 1) && - pgp_write_mpi(output, pksk->params.elgamal.g_to_k) && - pgp_write_mpi(output, pksk->params.elgamal.encrypted_m) - /* ?? && pgp_write_scalar(output, 0, 2); */ - ; - default: - (void) fprintf(stderr, - "pgp_write_pk_sesskey: bad algorithm\n"); - return 0; - } -} - -/** -\ingroup Core_WritePackets -\brief Writes MDC packet -\param hashed Hash for MDC -\param output Write settings -\return 1 if OK; else 0 -*/ - -unsigned -pgp_write_mdc(pgp_output_t *output, const uint8_t *hashed) -{ - /* write it out */ - return pgp_write_ptag(output, PGP_PTAG_CT_MDC) && - pgp_write_length(output, PGP_SHA1_HASH_SIZE) && - pgp_write(output, hashed, PGP_SHA1_HASH_SIZE); -} - -/** -\ingroup Core_WritePackets -\brief Writes Literal Data packet from buffer -\param data Buffer to write out -\param maxlen Max length of buffer -\param type Literal Data Type -\param output Write settings -\return 1 if OK; else 0 -*/ -unsigned -pgp_write_litdata(pgp_output_t *output, - const uint8_t *data, - const int maxlen, - const pgp_litdata_enum type) -{ - /* - * RFC4880 does not specify a meaning for filename or date. - * It is implementation-dependent. - * We will not implement them. - */ - /* \todo do we need to check text data for <cr><lf> line endings ? */ - return pgp_write_ptag(output, PGP_PTAG_CT_LITDATA) && - pgp_write_length(output, (unsigned)(1 + 1 + 4 + maxlen)) && - pgp_write_scalar(output, (unsigned)type, 1) && - pgp_write_scalar(output, 0, 1) && - pgp_write_scalar(output, 0, 4) && - pgp_write(output, data, (unsigned)maxlen); -} - -/** -\ingroup Core_WritePackets -\brief Writes Literal Data packet from contents of file -\param filename Name of file to read from -\param type Literal Data Type -\param output Write settings -\return 1 if OK; else 0 -*/ - -unsigned -pgp_fileread_litdata(const char *filename, - const pgp_litdata_enum type, - pgp_output_t *output) -{ - pgp_memory_t *mem; - unsigned ret; - int len; - - mem = pgp_memory_new(); - if (!pgp_mem_readfile(mem, filename)) { - (void) fprintf(stderr, "pgp_mem_readfile of '%s' failed\n", filename); - return 0; - } - len = (int)pgp_mem_len(mem); - ret = pgp_write_litdata(output, pgp_mem_data(mem), len, type); - pgp_memory_free(mem); - return ret; -} - -/** - \ingroup HighLevel_General - - \brief Writes contents of buffer into file - - \param filename Filename to write to - \param buf Buffer to write to file - \param len Size of buffer - \param overwrite Flag to set whether to overwrite an existing file - \return 1 if OK; 0 if error -*/ - -int -pgp_filewrite(const char *filename, const char *buf, - const size_t len, const unsigned overwrite) -{ - int flags; - int fd; - - flags = O_WRONLY | O_CREAT; - if (overwrite) { - flags |= O_TRUNC; - } else { - flags |= O_EXCL; - } -#ifdef O_BINARY - flags |= O_BINARY; -#endif - fd = open(filename, flags, 0600); - if (fd < 0) { - (void) fprintf(stderr, "can't open '%s'\n", filename); - return 0; - } - if (write(fd, buf, len) != (int)len) { - (void) close(fd); - return 0; - } - - return (close(fd) == 0); -} - -/** -\ingroup Core_WritePackets -\brief Write Symmetrically Encrypted packet -\param data Data to encrypt -\param len Length of data -\param output Write settings -\return 1 if OK; else 0 -\note Hard-coded to use AES256 -*/ -unsigned -pgp_write_symm_enc_data(const uint8_t *data, - const int len, - pgp_output_t * output) -{ - pgp_crypt_t crypt_info; - uint8_t *encrypted = (uint8_t *) NULL; - size_t encrypted_sz; - int done = 0; - - /* \todo assume AES256 for now */ - pgp_crypt_any(&crypt_info, PGP_SA_AES_256); - pgp_encrypt_init(&crypt_info); - - encrypted_sz = (size_t)(len + crypt_info.blocksize + 2); - if ((encrypted = calloc(1, encrypted_sz)) == NULL) { - (void) fprintf(stderr, "can't allocate %" PRIsize "d\n", - encrypted_sz); - return 0; - } - - done = (int)pgp_encrypt_se(&crypt_info, encrypted, data, (unsigned)len); - if (done != len) { - (void) fprintf(stderr, - "pgp_write_symm_enc_data: done != len\n"); - return 0; - } - - return pgp_write_ptag(output, PGP_PTAG_CT_SE_DATA) && - pgp_write_length(output, (unsigned)(1 + encrypted_sz)) && - pgp_write(output, data, (unsigned)len); -} - -/** -\ingroup Core_WritePackets -\brief Write a One Pass Signature packet -\param seckey Secret Key to use -\param hash_alg Hash Algorithm to use -\param sig_type Signature type -\param output Write settings -\return 1 if OK; else 0 -*/ -unsigned -pgp_write_one_pass_sig(pgp_output_t *output, - const pgp_seckey_t *seckey, - const pgp_hash_alg_t hash_alg, - const pgp_sig_type_t sig_type) -{ - uint8_t keyid[PGP_KEY_ID_SIZE]; - - pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, PGP_HASH_SHA1); /* XXX - hardcoded */ - return pgp_write_ptag(output, PGP_PTAG_CT_1_PASS_SIG) && - pgp_write_length(output, 1 + 1 + 1 + 1 + 8 + 1) && - pgp_write_scalar(output, 3, 1) /* version */ && - pgp_write_scalar(output, (unsigned)sig_type, 1) && - pgp_write_scalar(output, (unsigned)hash_alg, 1) && - pgp_write_scalar(output, (unsigned)seckey->pubkey.alg, 1) && - pgp_write(output, keyid, 8) && - pgp_write_scalar(output, 1, 1); -} diff --git a/netpgp/crypto.c b/netpgp/crypto.c deleted file mode 100644 index 8d2f976c28ae227b370143be1c73f42baea3e688..0000000000000000000000000000000000000000 --- a/netpgp/crypto.c +++ /dev/null @@ -1,763 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <string.h> - -#include "netpgp/types.h" -#include "netpgp/crypto.h" -#include "netpgp/readerwriter.h" -#include "netpgp/memory.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/signature.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/validate.h" - -/** -\ingroup Core_MPI -\brief Decrypt and unencode MPI -\param buf Buffer in which to write decrypted unencoded MPI -\param buflen Length of buffer -\param encmpi -\param seckey -\return length of MPI -\note only RSA at present -*/ -int -pgp_decrypt_decode_mpi(uint8_t *buf, - unsigned buflen, - const BIGNUM *g_to_k, - const BIGNUM *encmpi, - const pgp_seckey_t *seckey) -{ - unsigned mpisize; - uint8_t encmpibuf[NETPGP_BUFSIZ]; - uint8_t mpibuf[NETPGP_BUFSIZ]; - uint8_t gkbuf[NETPGP_BUFSIZ]; - int i; - int n; - - mpisize = (unsigned)BN_num_bytes(encmpi); - /* MPI can't be more than 65,536 */ - if (mpisize > sizeof(encmpibuf)) { - (void) fprintf(stderr, "mpisize too big %u\n", mpisize); - return -1; - } - switch (seckey->pubkey.alg) { - case PGP_PKA_RSA: - BN_bn2bin(encmpi, encmpibuf); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "encrypted", encmpibuf, 16); - } - n = pgp_rsa_private_decrypt(mpibuf, encmpibuf, - (unsigned)(BN_num_bits(encmpi) + 7) / 8, - &seckey->key.rsa, &seckey->pubkey.key.rsa); - if (n == -1) { - (void) fprintf(stderr, "ops_rsa_private_decrypt failure\n"); - return -1; - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "decrypted", mpibuf, 16); - } - if (n <= 0) { - return -1; - } - /* Decode EME-PKCS1_V1_5 (RFC 2437). */ - if (mpibuf[0] != 0 || mpibuf[1] != 2) { - return -1; - } - /* Skip the random bytes. */ - for (i = 2; i < n && mpibuf[i]; ++i) { - } - if (i == n || i < 10) { - return -1; - } - /* Skip the zero */ - i += 1; - /* this is the unencoded m buf */ - if ((unsigned) (n - i) <= buflen) { - (void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */ - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "decoded m", buf, (size_t)(n - i)); - } - return n - i; - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - (void) BN_bn2bin(g_to_k, gkbuf); - (void) BN_bn2bin(encmpi, encmpibuf); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "encrypted", encmpibuf, 16); - } - n = pgp_elgamal_private_decrypt(mpibuf, gkbuf, encmpibuf, - (unsigned)BN_num_bytes(encmpi), - &seckey->key.elgamal, &seckey->pubkey.key.elgamal); - if (n == -1) { - (void) fprintf(stderr, "ops_elgamal_private_decrypt failure\n"); - return -1; - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "decrypted", mpibuf, 16); - } - if (n <= 0) { - return -1; - } - /* Decode EME-PKCS1_V1_5 (RFC 2437). */ - if (mpibuf[0] != 2) { - fprintf(stderr, "mpibuf mismatch\n"); - return -1; - } - /* Skip the random bytes. */ - for (i = 1; i < n && mpibuf[i]; ++i) { - } - if (i == n || i < 10) { - fprintf(stderr, "175 n %d\n", n); - return -1; - } - /* Skip the zero */ - i += 1; - /* this is the unencoded m buf */ - if ((unsigned) (n - i) <= buflen) { - (void) memcpy(buf, mpibuf + i, (unsigned)(n - i)); /* XXX - Flexelint */ - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "decoded m", buf, (size_t)(n - i)); - } - return n - i; - default: - (void) fprintf(stderr, "pubkey algorithm wrong\n"); - return -1; - } -} - -/** -\ingroup Core_MPI -\brief RSA-encrypt an MPI -*/ -unsigned -pgp_rsa_encrypt_mpi(const uint8_t *encoded_m_buf, - const size_t sz_encoded_m_buf, - const pgp_pubkey_t * pubkey, - pgp_pk_sesskey_params_t * skp) -{ - - uint8_t encmpibuf[NETPGP_BUFSIZ]; - int n; - - if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.rsa.n)) { - (void) fprintf(stderr, "sz_encoded_m_buf wrong\n"); - return 0; - } - - n = pgp_rsa_public_encrypt(encmpibuf, encoded_m_buf, - sz_encoded_m_buf, &pubkey->key.rsa); - if (n == -1) { - (void) fprintf(stderr, "pgp_rsa_public_encrypt failure\n"); - return 0; - } - - if (n <= 0) - return 0; - - skp->rsa.encrypted_m = BN_bin2bn(encmpibuf, n, NULL); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "encrypted mpi", encmpibuf, 16); - } - return 1; -} - -/** -\ingroup Core_MPI -\brief Elgamal-encrypt an MPI -*/ -unsigned -pgp_elgamal_encrypt_mpi(const uint8_t *encoded_m_buf, - const size_t sz_encoded_m_buf, - const pgp_pubkey_t * pubkey, - pgp_pk_sesskey_params_t * skp) -{ - - uint8_t encmpibuf[NETPGP_BUFSIZ]; - uint8_t g_to_k[NETPGP_BUFSIZ]; - int n; - - if (sz_encoded_m_buf != (size_t)BN_num_bytes(pubkey->key.elgamal.p)) { - (void) fprintf(stderr, "sz_encoded_m_buf wrong\n"); - return 0; - } - - n = pgp_elgamal_public_encrypt(g_to_k, encmpibuf, encoded_m_buf, - sz_encoded_m_buf, &pubkey->key.elgamal); - if (n == -1) { - (void) fprintf(stderr, "pgp_elgamal_public_encrypt failure\n"); - return 0; - } - - if (n <= 0) - return 0; - - skp->elgamal.g_to_k = BN_bin2bn(g_to_k, n / 2, NULL); - skp->elgamal.encrypted_m = BN_bin2bn(encmpibuf, n / 2, NULL); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "encrypted mpi", encmpibuf, 16); - } - return 1; -} - -static pgp_cb_ret_t -write_parsed_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - - if (pgp_get_debug_level(__FILE__)) { - printf("write_parsed_cb: "); - //pgp_print_packet(&cbinfo->printstate, pkt); - } - if (pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT && cbinfo->printstate.skipping) { - puts("...end of skip"); - cbinfo->printstate.skipping = 0; - } - switch (pkt->tag) { - case PGP_PTAG_CT_UNARMOURED_TEXT: - printf("PGP_PTAG_CT_UNARMOURED_TEXT\n"); - if (!cbinfo->printstate.skipping) { - puts("Skipping..."); - cbinfo->printstate.skipping = 1; - } - if (fwrite(content->unarmoured_text.data, 1, - content->unarmoured_text.length, stdout) != content->unarmoured_text.length) { - fprintf(stderr, "unable to write unarmoured text data\n"); - cbinfo->printstate.skipping = 1; - } - break; - - case PGP_PTAG_CT_PK_SESSION_KEY: - return pgp_pk_sesskey_cb(pkt, cbinfo); - - case PGP_GET_SECKEY: - if (cbinfo->sshseckey) { - *content->get_seckey.seckey = cbinfo->sshseckey; - return PGP_KEEP_MEMORY; - } - return pgp_get_seckey_cb(pkt, cbinfo); - - case PGP_GET_PASSPHRASE: - if (cbinfo->cryptinfo.getpassphrase) { - return cbinfo->cryptinfo.getpassphrase(pkt, cbinfo); - } - break; - - case PGP_PTAG_CT_LITDATA_BODY: - return pgp_litdata_cb(pkt, cbinfo); - - case PGP_PTAG_CT_ARMOUR_HEADER: - case PGP_PTAG_CT_ARMOUR_TRAILER: - case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - case PGP_PTAG_CT_COMPRESSED: - case PGP_PTAG_CT_LITDATA_HEADER: - case PGP_PTAG_CT_SE_IP_DATA_BODY: - case PGP_PTAG_CT_SE_IP_DATA_HEADER: - case PGP_PTAG_CT_SE_DATA_BODY: - case PGP_PTAG_CT_SE_DATA_HEADER: - /* Ignore these packets */ - /* They're handled in parse_packet() */ - /* and nothing else needs to be done */ - break; - - default: - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "Unexpected packet tag=%d (0x%x)\n", - pkt->tag, - pkt->tag); - } - break; - } - - return PGP_RELEASE_MEMORY; -} - -/** -\ingroup HighLevel_Crypto -Encrypt a file -\param infile Name of file to be encrypted -\param outfile Name of file to write to. If NULL, name is constructed from infile -\param pubkey Public Key to encrypt file for -\param use_armour Write armoured text, if set -\param allow_overwrite Allow output file to be overwrwritten if it exists -\return 1 if OK; else 0 -*/ -#if 0 ////// -unsigned -pgp_encrypt_file(pgp_io_t *io, - const char *infile, - const char *outfile, - const pgp_key_t *key, - const unsigned use_armour, - const unsigned allow_overwrite, - const char *cipher) -{ - pgp_output_t *output; - pgp_memory_t *inmem; - pgp_keyring_t *rcpts; - int fd_out; - - __PGP_USED(io); - inmem = pgp_memory_new(); - if (!pgp_mem_readfile(inmem, infile)) { - return 0; - } - fd_out = pgp_setup_file_write(&output, outfile, allow_overwrite); - if (fd_out < 0) { - pgp_memory_free(inmem); - return 0; - } - - /* set armoured/not armoured here */ - if (use_armour) { - pgp_writer_push_armor_msg(output); - } - - if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) { - (void) fprintf(io->errs, - "netpgp_encrypt_buf: out of memory to create recipients list\n"); - return 0; - } - pgp_keyring_add(rcpts, key); - if(rcpts->keys == NULL){ - (void) fprintf(io->errs, - "netpgp_encrypt_buf: out of memory to add recipient\n"); - return 0; - } - /* Push the encrypted writer */ - if (!pgp_push_enc_se_ip(output, rcpts, cipher, 0)) { - pgp_memory_free(inmem); - return 0; - } - pgp_keyring_free(rcpts); - - /* This does the writing */ - pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem)); - - /* tidy up */ - pgp_memory_free(inmem); - pgp_teardown_file_write(output, fd_out); - - return 1; -} -#endif ////// - -/* encrypt the contents of the input buffer, and return the mem structure */ -pgp_memory_t * -pgp_encrypt_buf(pgp_io_t *io, - const void *input, - const size_t insize, - const pgp_keyring_t *pubkeys, - const unsigned use_armour, - const char *cipher, - unsigned raw) -{ - pgp_output_t *output; - pgp_memory_t *outmem; - - __PGP_USED(io); - if (input == NULL) { - (void) fprintf(io->errs, - "pgp_encrypt_buf: null memory\n"); - return 0; - } - - pgp_setup_memory_write(&output, &outmem, insize); - - /* set armoured/not armoured here */ - if (use_armour) { - pgp_writer_push_armor_msg(output); - } - - /* Push the encrypted writer */ - pgp_push_enc_se_ip(output, pubkeys, cipher, raw); - - /* This does the writing */ - pgp_write(output, input, (unsigned)insize); - - /* tidy up */ - pgp_writer_close(output); - pgp_output_delete(output); - - return outmem; -} - -/** - \ingroup HighLevel_Crypto - \brief Decrypt a file. - \param infile Name of file to be decrypted - \param outfile Name of file to write to. If NULL, the filename is constructed from the input filename, following GPG conventions. - \param keyring Keyring to use - \param use_armour Expect armoured text, if set - \param allow_overwrite Allow output file to overwritten, if set. - \param getpassfunc Callback to use to get passphrase -*/ -#if 0 ////// -unsigned -pgp_decrypt_file(pgp_io_t *io, - const char *infile, - const char *outfile, - pgp_keyring_t *secring, - pgp_keyring_t *pubring, - const unsigned use_armour, - const unsigned allow_overwrite, - const unsigned sshkeys, - void *passfp, - int numtries, - pgp_cbfunc_t *getpassfunc) -{ - pgp_stream_t *parse = NULL; - const int printerrors = 1; - char *filename = NULL; - int fd_in; - int fd_out; - - /* setup for reading from given input file */ - fd_in = pgp_setup_file_read(io, &parse, infile, - NULL, - write_parsed_cb, - 0); - if (fd_in < 0) { - perror(infile); - return 0; - } - /* setup output filename */ - if (outfile) { - fd_out = pgp_setup_file_write(&parse->cbinfo.output, outfile, - allow_overwrite); - if (fd_out < 0) { - perror(outfile); - pgp_teardown_file_read(parse, fd_in); - return 0; - } - } else { - const int suffixlen = 4; - const char *suffix = infile + strlen(infile) - suffixlen; - unsigned filenamelen; - - if (strcmp(suffix, ".gpg") == 0 || - strcmp(suffix, ".asc") == 0) { - filenamelen = (unsigned)(strlen(infile) - strlen(suffix)); - if ((filename = calloc(1, filenamelen + 1)) == NULL) { - (void) fprintf(stderr, "can't allocate %" PRIsize "d bytes\n", - (size_t)(filenamelen + 1)); - return 0; - } - (void) strncpy(filename, infile, filenamelen); - filename[filenamelen] = 0x0; - } - - fd_out = pgp_setup_file_write(&parse->cbinfo.output, - filename, allow_overwrite); - if (fd_out < 0) { - perror(filename); - free(filename); - pgp_teardown_file_read(parse, fd_in); - return 0; - } - } - - /* \todo check for suffix matching armour param */ - - /* setup for writing decrypted contents to given output file */ - - /* setup keyring and passphrase callback */ - parse->cbinfo.cryptinfo.secring = secring; - parse->cbinfo.passfp = passfp; - parse->cbinfo.cryptinfo.getpassphrase = getpassfunc; - parse->cbinfo.cryptinfo.pubring = pubring; - parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL; - parse->cbinfo.numtries = numtries; - - /* Set up armour/passphrase options */ - if (use_armour) { - pgp_reader_push_dearmour(parse); - } - - /* Do it */ - pgp_parse(parse, printerrors); - - /* Unsetup */ - if (use_armour) { - pgp_reader_pop_dearmour(parse); - } - - /* if we didn't get the passphrase, unlink output file */ - if (!parse->cbinfo.gotpass) { - (void) unlink((filename) ? filename : outfile); - } - - if (filename) { - pgp_teardown_file_write(parse->cbinfo.output, fd_out); - free(filename); - } - pgp_teardown_file_read(parse, fd_in); - /* \todo cleardown crypt */ - - return 1; -} -#endif ////// - -/* decrypt an area of memory */ -pgp_memory_t * -pgp_decrypt_buf(pgp_io_t *io, - const void *input, - const size_t insize, - pgp_keyring_t *secring, - pgp_keyring_t *pubring, - const unsigned use_armour, - const unsigned sshkeys, - void *passfp, - int numtries, - pgp_cbfunc_t *getpassfunc) -{ - pgp_stream_t *parse = NULL; - pgp_memory_t *outmem; - pgp_memory_t *inmem; - const int printerrors = 1; - - if (input == NULL) { - (void) fprintf(io->errs, - "pgp_encrypt_buf: null memory\n"); - return 0; - } - - inmem = pgp_memory_new(); - pgp_memory_add(inmem, input, insize); - - /* set up to read from memory */ - pgp_setup_memory_read(io, &parse, inmem, - NULL, - write_parsed_cb, - 0); - - /* setup for writing decrypted contents to given output file */ - pgp_setup_memory_write(&parse->cbinfo.output, &outmem, insize); - - /* setup keyring and passphrase callback */ - parse->cbinfo.cryptinfo.secring = secring; - parse->cbinfo.cryptinfo.pubring = pubring; - parse->cbinfo.passfp = passfp; - parse->cbinfo.cryptinfo.getpassphrase = getpassfunc; - parse->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL; - parse->cbinfo.numtries = numtries; - - /* Set up armour/passphrase options */ - if (use_armour) { - pgp_reader_push_dearmour(parse); - } - - /* Do it */ - pgp_parse(parse, printerrors); - - /* Unsetup */ - if (use_armour) { - pgp_reader_pop_dearmour(parse); - } - - /* tidy up */ - pgp_teardown_memory_read(parse, inmem); - - pgp_writer_close(parse->cbinfo.output); - pgp_output_delete(parse->cbinfo.output); - - /* if we didn't get the passphrase, return NULL */ - return (parse->cbinfo.gotpass) ? outmem : NULL; -} - -/* Special callback for decrypt and validate */ -static pgp_cb_ret_t -pgp_decrypt_and_validate_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - pgp_cb_ret_t ret_write_cb = PGP_RELEASE_MEMORY; - pgp_cb_ret_t ret_validate_cb = PGP_RELEASE_MEMORY; - - ret_write_cb = write_parsed_cb(pkt, cbinfo); - - /* Filter pkt sent to validate callback */ - switch (pkt->tag) { - case PGP_PTAG_CT_LITDATA_BODY: - case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY: - case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */ - case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */ - ret_validate_cb = validate_data_cb(pkt, cbinfo); - break; - default: - break; - } - - /* Only validate_data_cb takes some arguments. - * Otherwise, stacked callbacks would have been necessary - */ - return (ret_write_cb == PGP_KEEP_MEMORY || - ret_validate_cb == PGP_KEEP_MEMORY) ? - PGP_KEEP_MEMORY : PGP_RELEASE_MEMORY; -} - -/* decrypt and validate an area of memory */ -pgp_memory_t * -pgp_decrypt_and_validate_buf(pgp_io_t *io, - pgp_validation_t *result, - const void *input, - const size_t insize, - pgp_keyring_t *secring, - pgp_keyring_t *pubring, - const unsigned use_armour, - key_id_t **recipients_key_ids, - unsigned *recipients_count) -{ - // historical code bloat... - const unsigned sshkeys = 0; - void *passfp = NULL; - int numtries = -1; - pgp_cbfunc_t *getpassfunc = NULL; - - validate_data_cb_t validation; - pgp_stream_t *stream = NULL; - pgp_memory_t *outmem; - pgp_memory_t *inmem; - const int printerrors = 1; - - if (input == NULL) { - (void) fprintf(io->errs, - "pgp_encrypt_buf: null memory\n"); - return 0; - } - - inmem = pgp_memory_new(); - pgp_memory_add(inmem, input, insize); - - /* set up to read from memory */ - pgp_setup_memory_read(io, &stream, inmem, - &validation, - pgp_decrypt_and_validate_cb, - 1); - - /* Set verification reader and handling options */ - (void) memset(&validation, 0x0, sizeof(validation)); - validation.result = result; - validation.keyring = pubring; - validation.mem = pgp_memory_new(); - pgp_memory_init(validation.mem, 128); - - /* setup for writing decrypted contents */ - pgp_setup_memory_write(&stream->cbinfo.output, &outmem, insize); - - /* setup keyring and passphrase callback */ - stream->cbinfo.cryptinfo.secring = secring; - stream->cbinfo.cryptinfo.pubring = pubring; - stream->cbinfo.passfp = passfp; - stream->cbinfo.cryptinfo.getpassphrase = getpassfunc; - stream->cbinfo.sshseckey = (sshkeys) ? &secring->keys[0].key.seckey : NULL; - stream->cbinfo.numtries = numtries; - - /* Set up armour */ - if (use_armour) { - pgp_reader_push_dearmour(stream); - } - - /* Do it */ - pgp_parse(stream, printerrors); - - /* Unsetup */ - if (use_armour) { - pgp_reader_pop_dearmour(stream); - } - - *recipients_count = stream->cbinfo.cryptinfo.recipients_key_idsc; - if (*recipients_count == 0) { - *recipients_key_ids = NULL; - } else { - *recipients_key_ids = calloc(sizeof(key_id_t),*recipients_count); - if( *recipients_key_ids != NULL) - { - memcpy(*recipients_key_ids, - stream->cbinfo.cryptinfo.recipients_key_idss, - sizeof(key_id_t) * *recipients_count); - } - } - - if( *recipients_key_ids == NULL) - { - pgp_memory_free(outmem); - *recipients_count = 0; - outmem = NULL; - } - - /* tidy up */ - pgp_writer_close(stream->cbinfo.output); - pgp_output_delete(stream->cbinfo.output); - - pgp_teardown_memory_read(stream, inmem); - pgp_memory_free(validation.mem); - - return outmem; -} diff --git a/netpgp/keyring.c b/netpgp/keyring.c deleted file mode 100644 index 0a33921e7be110f73fa99b15a9210264660f0aae..0000000000000000000000000000000000000000 --- a/netpgp/keyring.c +++ /dev/null @@ -1,1647 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#include <regex.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "netpgp/types.h" -#include "netpgp/keyring.h" -#include "netpgp/packet-parse.h" -#include "netpgp/signature.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/readerwriter.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/packet.h" -#include "netpgp/crypto.h" -#include "netpgp/validate.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/netpgpdigest.h" - - - -/** - \ingroup HighLevel_Keyring - - \brief Creates a new pgp_key_t struct - - \return A new pgp_key_t struct, initialised to zero. - - \note The returned pgp_key_t struct must be freed after use with pgp_keydata_free. -*/ - -pgp_key_t * -pgp_keydata_new(void) -{ - return calloc(1, sizeof(pgp_key_t)); -} - - -/** - \ingroup HighLevel_Keyring - - \brief Frees key's allocated memory - - \param keydata Key to be freed. - - \note This does not free the keydata itself, but any other memory alloc-ed by it. -*/ -void -pgp_key_free(pgp_key_t *key) -{ - unsigned n; - - if (key->type == PGP_PTAG_CT_PUBLIC_KEY) { - pgp_pubkey_free(&key->key.pubkey); - } else { - pgp_seckey_free(&key->key.seckey); - } - - for (n = 0; n < key->directsigc; ++n) { - pgp_free_sig_info(&key->directsigs[n].siginfo); - pgp_subpacket_free(&key->directsigs[n].packet); - } - FREE_ARRAY(key, directsig); - - for (n = 0; n < key->uidc; ++n) { - pgp_userid_free(&key->uids[n]); - } - FREE_ARRAY(key, uid); - - for (n = 0; n < key->uidsigc; ++n) { - pgp_free_sig_info(&key->uidsigs[n].siginfo); - pgp_subpacket_free(&key->uidsigs[n].packet); - } - FREE_ARRAY(key, uidsig); - - for (n = 0; n < key->subkeyc; ++n) { - if (key->type == PGP_PTAG_CT_PUBLIC_KEY) { - pgp_pubkey_free(&key->subkeys[n].key.pubkey); - } else { - pgp_seckey_free(&key->subkeys[n].key.seckey); - } - } - FREE_ARRAY(key, subkey); - - for (n = 0; n < key->subkeysigc; ++n) { - pgp_free_sig_info(&key->subkeysigs[n].siginfo); - pgp_subpacket_free(&key->subkeysigs[n].packet); - } - FREE_ARRAY(key, subkeysig); -} - -/** - \ingroup HighLevel_Keyring - - \brief Frees keydata and its memory - - \param keydata Key to be freed. - - \note This frees the keydata itself, as well as any other memory alloc-ed by it. -*/ -void -pgp_keydata_free(pgp_key_t *keydata) -{ - pgp_key_free(keydata); - free(keydata); -} - -static unsigned siginfo_in_time(pgp_sig_info_t *siginfo){ - time_t now; - now = time(NULL); - /* in sig validity time frame */ - return now >= siginfo->birthtime && ( - siginfo->key_expiry == 0 || - now < siginfo->birthtime + - siginfo->key_expiry); -} - -const int32_t -pgp_key_find_uid_cond( - const pgp_key_t *key, - unsigned(*uidcond) ( uint8_t *, void *), - void *uidcondarg, - unsigned(*sigcond) ( const pgp_sig_info_t *, void *), - void *sigcondarg, - time_t *youngest, - unsigned checkrevoke, - unsigned checkexpiry) -{ - unsigned uididx = 0; - unsigned uidsigidx = 0; - int32_t res = -1; /* Not found */ - int32_t lastgood; - uint8_t **uidp; - pgp_uidsig_t *uidsigp; - time_t yngst = 0; - - /* If not maximum age given, take default */ - if(!youngest) - youngest = &yngst; - - /* Loop over key's user ids*/ - uidp = key->uids; - for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++) - { - if(uidcond && !uidcond(*uidp, uidcondarg)) continue; - - lastgood = res; - /* Loop over key's user ids sigs */ - uidsigp = key->uidsigs; - for (uidsigidx = 0 ; uidsigidx < key->uidsigc; uidsigidx++, uidsigp++) - { - /* matching selected user id */ - if(uidsigp->uid == uididx) - { - /* if uid is revoked */ - /* revoke on secret keys has no effect*/ - if(uidsigp->siginfo.type == PGP_SIG_REV_CERT) - { - /* ignore revocation if secret */ - if(!checkrevoke) - continue; - - /* revert to last good candidate */ - res = lastgood; - break; /* jump to next uid */ - } - - /* in sig validity time frame */ - if(!checkexpiry || siginfo_in_time(&uidsigp->siginfo)) - { - /* sig cond is ok ? */ - if(!sigcond || sigcond(&uidsigp->siginfo, sigcondarg)) - { - /* youngest signature is deciding */ - if(uidsigp->siginfo.birthtime > *youngest) - { - *youngest = uidsigp->siginfo.birthtime; - res = uididx; - } - } - } - } - } - } - return res; -} - -/* - * Returns : - * -2 not found - * -1 match is priamary key - * >=0 index of matching valid subkey - * */ -const int32_t -pgp_key_find_key_conds( - pgp_key_t *key, - unsigned(*keycond) ( const pgp_pubkey_t *, const uint8_t *, void*), - void *keycondarg, - unsigned(*sigcond) ( const pgp_sig_info_t *, void*), - void *sigcondarg, - unsigned checkrevoke, - unsigned checkexpiry) -{ - unsigned subkeyidx = 0; - unsigned subkeysigidx = 0; - unsigned directsigidx = 0; - int32_t res = -2; /* Not found */ - int32_t lastgood; - pgp_subkey_t *subkeyp; - pgp_subkeysig_t *subkeysigp; - pgp_directsig_t *directsigp; - time_t youngest; - - youngest = 0; - - /* check pubkey first */ - if(!keycond || keycond(pgp_key_get_pubkey(key), - key->pubkeyid, keycondarg)){ - - int32_t uidres; - - /* Loop over key's direct sigs */ - directsigp = key->directsigs; - - for (directsigidx = 0 ; directsigidx < key->directsigc; - directsigidx++, directsigp++) - { - /* if direct is revoked */ - if(directsigp->siginfo.type == PGP_SIG_REV_KEY) - { - /* ignore revocation if secret */ - if(!checkrevoke) - continue; - - return -2; /* Key is globally revoked, no result */ - } - - /* in sig validity time frame */ - if(!checkexpiry || siginfo_in_time(&directsigp->siginfo)) - { - /* condition on sig is ok */ - if(!sigcond || sigcond(&directsigp->siginfo, sigcondarg)) - { - /* youngest signature is deciding */ - if(directsigp->siginfo.birthtime > youngest) - { - youngest = directsigp->siginfo.birthtime; - res = -1; /* Primary key is a candidate */ - } - } - } - } - - uidres = pgp_key_find_uid_cond( - key, NULL, NULL, sigcond, sigcondarg, &youngest, - checkrevoke, checkexpiry); - - /* if matching uid sig, then primary is matching key */ - if(uidres != -1){ - res = -1; - } - } - - /* Loop over key's subkeys */ - subkeyp = key->subkeys; - for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++) - { - lastgood = res; - - subkeysigp = key->subkeysigs; - - /* Skip this subkey if key condition not met */ - if(keycond && !keycond(&subkeyp->key.pubkey, subkeyp->id, keycondarg)) - continue; - - /* Loop over key's subkeys sigs */ - for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc; - subkeysigidx++, subkeysigp++) - { - /* matching selected subkey */ - if(subkeysigp->subkey == subkeyidx) - { - /* if subkey is revoked */ - if(subkeysigp->siginfo.type == PGP_SIG_REV_SUBKEY) - { - /* ignore revocation if secret */ - if(!checkrevoke) - continue; - - /* revert to last good candidate */ - res = lastgood; - break; /* jump to next subkey */ - } - - /* in sig validity time frame */ - if(!checkexpiry || siginfo_in_time(&subkeysigp->siginfo)) - { - /* subkey sig condition is ok */ - if(!sigcond || sigcond(&subkeysigp->siginfo, sigcondarg)) - { - /* youngest signature is deciding */ - if(subkeysigp->siginfo.birthtime > youngest) - { - youngest = subkeysigp->siginfo.birthtime; - res = subkeyidx; - } - } - } - } - } - } - return res; -} - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the public key in the given keydata. - \param keydata - - \return Pointer to public key - - \note This is not a copy, do not free it after use. -*/ - -pgp_pubkey_t * -pgp_key_get_pubkey(pgp_key_t *keydata) -{ - return (keydata->type == PGP_PTAG_CT_PUBLIC_KEY) ? - &keydata->key.pubkey : - &keydata->key.seckey.pubkey; -} - -pgp_pubkey_t * -pgp_key_get_subpubkey(pgp_key_t *key, int32_t subkeyidx) -{ - return (key->type == PGP_PTAG_CT_PUBLIC_KEY) ? - &key->subkeys[subkeyidx].key.pubkey : - &key->subkeys[subkeyidx].key.seckey.pubkey; -} - -pgp_seckey_t * -pgp_key_get_subseckey(pgp_key_t *key, int32_t subkeyidx) -{ - return (key->type == PGP_PTAG_CT_SECRET_KEY) ? - &key->subkeys[subkeyidx].key.seckey : - NULL; -} -static pgp_pubkey_t * -key_get_pubkey_from_subidx( - pgp_key_t *key, - const uint8_t **id, - int32_t subkeyidx) -{ - if(subkeyidx == -2){ - return NULL; - } - - if(subkeyidx != -1) - { - if(id) - *id = key->subkeys[subkeyidx].id; - - return pgp_key_get_subpubkey(key, subkeyidx); - - } - - if(id) - *id = key->pubkeyid; - - return pgp_key_get_pubkey(key); -} - -static pgp_seckey_t * -key_get_seckey_from_subidx( - pgp_key_t *key, - const uint8_t **id, - int32_t subkeyidx) -{ - if(subkeyidx == -2){ - return NULL; - } - - if(subkeyidx != -1) - { - if(id) - *id = key->subkeys[subkeyidx].id; - - return pgp_key_get_subseckey(key, subkeyidx); - - } - - if(id) - *id = key->pubkeyid; - - return pgp_get_seckey(key); -} - -static unsigned is_signing_role(const pgp_sig_info_t *siginfo, void *arg) -{ - return siginfo->key_flags & PGP_KEYFLAG_SIGN_DATA; -} - -/* Get a pub key to check signature */ -pgp_pubkey_t * -pgp_key_get_sigkey(pgp_key_t *key) -{ - int32_t subkeyidx = - pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 0, 0); - return key_get_pubkey_from_subidx(key, NULL, subkeyidx); -} - -/* Get a sec key to write a signature */ -pgp_seckey_t * -pgp_key_get_certkey(pgp_key_t *key) -{ - int32_t subkeyidx = - pgp_key_find_key_conds(key, NULL, NULL, &is_signing_role, NULL, 1, 0); - return key_get_seckey_from_subidx(key, NULL, subkeyidx); -} - -static unsigned is_encryption_role(const pgp_sig_info_t *siginfo, void *arg) -{ - return siginfo->key_flags & PGP_KEYFLAG_ENC_COMM; -} - -pgp_pubkey_t * -pgp_key_get_enckey(pgp_key_t *key, const uint8_t **id) -{ - int32_t subkeyidx = - pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 1, 0); - - return key_get_pubkey_from_subidx(key, id, subkeyidx); -} - -pgp_seckey_t * -pgp_key_get_deckey(pgp_key_t *key, const uint8_t **id) -{ - int32_t subkeyidx = - pgp_key_find_key_conds(key, NULL, NULL, &is_encryption_role, NULL, 0, 0); - - return key_get_seckey_from_subidx(key, id, subkeyidx); -} - -static unsigned primary_uid_sigcond(const pgp_sig_info_t *siginfo, void *arg) -{ - return siginfo->primary_userid; -} - -const int32_t pgp_key_get_uid0(pgp_key_t *key) -{ - int32_t res = - pgp_key_find_uid_cond(key, NULL, NULL, &primary_uid_sigcond, NULL, NULL, 1, 0); - - /* arbitrarily use youngest uid if no primary is found */ - return res == -1 ? - pgp_key_find_uid_cond(key, NULL, NULL, NULL, NULL, NULL, 1, 0): - res; -} - -const uint8_t *pgp_key_get_primary_userid(pgp_key_t *key) -{ - const int32_t uid0 = pgp_key_get_uid0(key); - if( uid0 >= 0 && key->uids && key->uidc > uid0) - { - return key->uids[uid0]; - } - return NULL; -} - -unsigned key_bit_len(const pgp_pubkey_t *key) -{ - switch (key->alg) { - case PGP_PKA_DSA: - return BN_num_bits(key->key.dsa.p); - - case PGP_PKA_RSA: - return BN_num_bits(key->key.rsa.n); - - case PGP_PKA_ELGAMAL: - return BN_num_bits(key->key.elgamal.p); - - default: - return 0; - } -} - -unsigned key_is_weak( - const pgp_pubkey_t *key, - const uint8_t *keyid, - void *arg) -{ - unsigned kbl; - pgp_key_rating_t *res; - - res = (pgp_key_rating_t*)arg; - kbl = key_bit_len(key); - - if(kbl == 0) - { - *res = PGP_INVALID; - } - else if(kbl < 1024) - { - *res = PGP_TOOSHORT; - } - else if(kbl == 1024 && key->alg == PGP_PKA_RSA) - { - *res = PGP_WEAK; - } - - return 0; -} - -const pgp_key_rating_t pgp_key_get_rating(pgp_key_t *key) -{ - /* keys exist in rings only if valid */ - pgp_key_rating_t res = PGP_VALID; - - pgp_key_find_key_conds(key, &key_is_weak, (void*)&res, NULL, NULL, 0, 0); - - if(res == PGP_VALID) - { - if(pgp_key_find_key_conds( - key, NULL, NULL, NULL, NULL, 1, 0) == -2) - { - return PGP_REVOKED; - } - if(pgp_key_find_key_conds( - key, NULL, NULL, NULL, NULL, 0, 1) == -2) - { - return PGP_EXPIRED; - } - } - - return res; -} -/** -\ingroup HighLevel_KeyGeneral - -\brief Check whether this is a secret key or not. -*/ - -unsigned -pgp_is_key_secret(pgp_key_t *data) -{ - return data->type != PGP_PTAG_CT_PUBLIC_KEY; -} - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the secret key in the given keydata. - - \note This is not a copy, do not free it after use. - - \note This returns a const. If you need to be able to write to this - pointer, use pgp_get_writable_seckey -*/ - -pgp_seckey_t * -pgp_get_seckey(pgp_key_t *data) -{ - return (data->type == PGP_PTAG_CT_SECRET_KEY) ? - &data->key.seckey : NULL; -} - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the secret key in the given keydata. - - \note This is not a copy, do not free it after use. - - \note If you do not need to be able to modify this key, there is an - equivalent read-only function pgp_get_seckey. -*/ - -pgp_seckey_t * -pgp_get_writable_seckey(pgp_key_t *data) -{ - return (data->type == PGP_PTAG_CT_SECRET_KEY) ? - &data->key.seckey : NULL; -} - -/* utility function to zero out memory */ -void -pgp_forget(void *vp, unsigned size) -{ - (void) memset(vp, 0x0, size); -} - -typedef struct { - FILE *passfp; - const pgp_key_t *key; - char *passphrase; - pgp_seckey_t *seckey; -} decrypt_t; - -// FIXME : support encrypted seckeys again -// static pgp_cb_ret_t -// decrypt_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -// { -// const pgp_contents_t *content = &pkt->u; -// decrypt_t *decrypt; -// char pass[MAX_PASSPHRASE_LENGTH]; -// -// decrypt = pgp_callback_arg(cbinfo); -// switch (pkt->tag) { -// case PGP_PARSER_PTAG: -// case PGP_PTAG_CT_USER_ID: -// case PGP_PTAG_CT_SIGNATURE: -// case PGP_PTAG_CT_SIGNATURE_HEADER: -// case PGP_PTAG_CT_SIGNATURE_FOOTER: -// case PGP_PTAG_CT_TRUST: -// break; -// -// case PGP_GET_PASSPHRASE: -// (void) pgp_getpassphrase(decrypt->passfp, pass, sizeof(pass)); -// *content->skey_passphrase.passphrase = netpgp_strdup(pass); -// pgp_forget(pass, (unsigned)sizeof(pass)); -// return PGP_KEEP_MEMORY; -// -// case PGP_PARSER_ERRCODE: -// switch (content->errcode.errcode) { -// case PGP_E_P_MPI_FORMAT_ERROR: -// /* Generally this means a bad passphrase */ -// fprintf(stderr, "Bad passphrase!\n"); -// return PGP_RELEASE_MEMORY; -// -// case PGP_E_P_PACKET_CONSUMED: -// /* And this is because of an error we've accepted */ -// return PGP_RELEASE_MEMORY; -// default: -// break; -// } -// (void) fprintf(stderr, "parse error: %s\n", -// pgp_errcode(content->errcode.errcode)); -// return PGP_FINISHED; -// -// case PGP_PARSER_ERROR: -// fprintf(stderr, "parse error: %s\n", content->error); -// return PGP_FINISHED; -// -// case PGP_PTAG_CT_SECRET_KEY: -// if ((decrypt->seckey = calloc(1, sizeof(*decrypt->seckey))) == NULL) { -// (void) fprintf(stderr, "decrypt_cb: bad alloc\n"); -// return PGP_FINISHED; -// } -// decrypt->seckey->checkhash = calloc(1, PGP_CHECKHASH_SIZE); -// *decrypt->seckey = content->seckey; /* XXX WTF ? */ -// return PGP_KEEP_MEMORY; -// -// case PGP_PARSER_PACKET_END: -// /* nothing to do */ -// break; -// -// default: -// fprintf(stderr, "Unexpected tag %d (0x%x)\n", pkt->tag, -// pkt->tag); -// return PGP_FINISHED; -// } -// -// return PGP_RELEASE_MEMORY; -// } - -// FIXME : support encrypted seckeys again -// /** -// \ingroup Core_Keys -// \brief Decrypts secret key from given keydata with given passphrase -// \param key Key from which to get secret key -// \param passphrase Passphrase to use to decrypt secret key -// \return secret key -// */ -// pgp_seckey_t * -// pgp_decrypt_seckey(const pgp_key_t *key, void *passfp) -// { -// pgp_stream_t *stream; -// const int printerrors = 1; -// decrypt_t decrypt; -// -// (void) memset(&decrypt, 0x0, sizeof(decrypt)); -// decrypt.key = key; -// decrypt.passfp = passfp; -// stream = pgp_new(sizeof(*stream)); -// pgp_keydata_reader_set(stream, key); -// pgp_set_callback(stream, decrypt_cb, &decrypt); -// stream->readinfo.accumulate = 1; -// pgp_parse(stream, !printerrors); -// return decrypt.seckey; -// } - -/* \todo check where userid pointers are copied */ -/** -\ingroup Core_Keys -\brief Copy user id, including contents -\param dst Destination User ID -\param src Source User ID -\note If dst already has a userid, it will be freed. -*/ -uint8_t * -pgp_copy_userid(uint8_t **dst, const uint8_t *src) -{ - size_t len; - - len = strlen((const char *) src); - if (*dst) { - free(*dst); - } - if ((*dst = calloc(1, len + 1)) == NULL) { - (void) fprintf(stderr, "pgp_copy_userid: bad alloc\n"); - } else { - (void) memcpy(*dst, src, len); - } - return *dst; -} - -/* \todo check where pkt pointers are copied */ -/** -\ingroup Core_Keys -\brief Copy packet, including contents -\param dst Destination packet -\param src Source packet -\note If dst already has a packet, it will be freed. -*/ -pgp_subpacket_t * -pgp_copy_packet(pgp_subpacket_t *dst, const pgp_subpacket_t *src) -{ - if (dst->raw) { - free(dst->raw); - } - if ((dst->raw = calloc(1, src->length)) == NULL) { - (void) fprintf(stderr, "pgp_copy_packet: bad alloc\n"); - } else { - dst->length = src->length; - (void) memcpy(dst->raw, src->raw, src->length); - } - - return dst; -} - -#if 0 -/** -\ingroup Core_Keys -\brief Add User ID to key -\param key Key to which to add User ID -\param userid User ID to add -\return Pointer to new User ID -*/ -uint8_t * -pgp_add_userid(pgp_key_t *key, const uint8_t *userid) -{ - uint8_t **uidp; - - EXPAND_ARRAY(key, uid); - /* initialise new entry in array */ - uidp = &key->uids[key->uidc++]; - *uidp = NULL; - /* now copy it */ - return pgp_copy_userid(uidp, userid); -} -#endif - -void print_packet_hex(const pgp_subpacket_t *pkt); - -/** -\ingroup Core_Keys -\brief Add selfsigned User ID to key -\param keydata Key to which to add user ID -\param userid Self-signed User ID to add -\return 1 if OK; else 0 -*/ -#if 0 ////// -unsigned -pgp_add_selfsigned_userid(pgp_key_t *skey, pgp_key_t *pkey, const uint8_t *userid, time_t key_expiry) -{ - pgp_create_sig_t *sig; - pgp_subpacket_t sigpacket; - pgp_memory_t *mem_sig = NULL; - pgp_output_t *sigoutput = NULL; - - /* - * create signature packet for this userid - */ - - /* create sig for this pkt */ - sig = pgp_create_sig_new(); - pgp_sig_start_key_sig(sig, &skey->key.seckey.pubkey, userid, PGP_CERT_POSITIVE); - - pgp_add_creation_time(sig, time(NULL)); - pgp_add_key_expiration_time(sig, key_expiry); - pgp_add_issuer_keyid(sig, skey->pubkeyid); - pgp_add_primary_userid(sig, 1); - pgp_add_key_flags(sig, PGP_KEYFLAG_SIGN_DATA|PGP_KEYFLAG_ENC_COMM); - pgp_add_key_prefs(sig); - pgp_add_key_features(sig); - - pgp_end_hashed_subpkts(sig); - - pgp_setup_memory_write(&sigoutput, &mem_sig, 128); - pgp_write_sig(sigoutput, sig, &skey->key.seckey.pubkey, &skey->key.seckey); - - /* add this packet to key */ - sigpacket.length = pgp_mem_len(mem_sig); - sigpacket.raw = pgp_mem_data(mem_sig); - - /* add user id and signature to key */ - pgp_update_userid(skey, userid, &sigpacket, &sig->sig.info); - if(pkey) - pgp_update_userid(pkey, userid, &sigpacket, &sig->sig.info); - - /* cleanup */ - pgp_create_sig_delete(sig); - pgp_output_delete(sigoutput); - pgp_memory_free(mem_sig); - - return 1; -} -#endif ////// - -unsigned -pgp_key_revoke(pgp_key_t *skey, pgp_key_t *pkey, uint8_t code, const char *reason) -{ - pgp_create_sig_t *sig; - pgp_subpacket_t sigpacket; - pgp_memory_t *mem_sig = NULL; - pgp_output_t *sigoutput = NULL; - - sig = pgp_create_sig_new(); - pgp_sig_start_key_rev( - sig, &skey->key.seckey.pubkey, - PGP_SIG_REV_KEY); - - pgp_add_creation_time(sig, time(NULL)); - pgp_add_issuer_keyid(sig, skey->pubkeyid); - pgp_add_revocation_reason(sig, code, reason); - pgp_end_hashed_subpkts(sig); - - pgp_setup_memory_write(&sigoutput, &mem_sig, 128); - pgp_write_sig(sigoutput, sig, &skey->key.seckey.pubkey, &skey->key.seckey); - - sigpacket.length = pgp_mem_len(mem_sig); - sigpacket.raw = pgp_mem_data(mem_sig); - - pgp_add_directsig(skey, &sigpacket, &sig->sig.info); - pgp_add_directsig(pkey, &sigpacket, &sig->sig.info); - - /* cleanup */ - pgp_create_sig_delete(sig); - pgp_output_delete(sigoutput); - pgp_memory_free(mem_sig); - - return 1; -} - -/** -\ingroup Core_Keys -\brief Initialise pgp_key_t -\param keydata Keydata to initialise -\param type PGP_PTAG_CT_PUBLIC_KEY or PGP_PTAG_CT_SECRET_KEY -*/ -void -pgp_keydata_init(pgp_key_t *keydata, const pgp_content_enum type) -{ - if (keydata->type != PGP_PTAG_CT_RESERVED) { - (void) fprintf(stderr, - "pgp_keydata_init: wrong keydata type\n"); - } else if (type != PGP_PTAG_CT_PUBLIC_KEY && - type != PGP_PTAG_CT_SECRET_KEY) { - (void) fprintf(stderr, "pgp_keydata_init: wrong type\n"); - } else { - keydata->type = type; - } -} - -/** - \ingroup HighLevel_KeyringRead - - \brief Reads a keyring from a file - - \param keyring Pointer to an existing pgp_keyring_t struct - \param armour 1 if file is armoured; else 0 - \param filename Filename of keyring to be read - - \return pgp 1 if OK; 0 on error - - \note Keyring struct must already exist. - - \note Can be used with either a public or secret keyring. - - \note You must call pgp_keyring_free() after usage to free alloc-ed memory. - - \note If you call this twice on the same keyring struct, without calling - pgp_keyring_free() between these calls, you will introduce a memory leak. - - \sa pgp_keyring_read_from_mem() - \sa pgp_keyring_free() - -*/ -#if 0 ////// -unsigned -pgp_keyring_fileread(pgp_io_t *io, - pgp_keyring_t *pubring, - pgp_keyring_t *secring, - const unsigned armour, - const char *filename) -{ - return pgp_filter_keys_fileread( - io, - pubring, - secring, - NULL /*certring -> self cert */, - armour, - filename); -} -#endif ////// - -/** - \ingroup HighLevel_KeyringRead - - \brief Reads a keyring from memory - - \param keyring Pointer to existing pgp_keyring_t struct - \param armour 1 if file is armoured; else 0 - \param mem Pointer to a pgp_memory_t struct containing keyring to be read - - \return pgp 1 if OK; 0 on error - - \note Keyring struct must already exist. - - \note Can be used with either a public or secret keyring. - - \note You must call pgp_keyring_free() after usage to free alloc-ed memory. - - \note If you call this twice on the same keyring struct, without calling - pgp_keyring_free() between these calls, you will introduce a memory leak. - - \sa pgp_keyring_fileread - \sa pgp_keyring_free -*/ -unsigned -pgp_keyring_read_from_mem(pgp_io_t *io, - pgp_keyring_t *pubring, - pgp_keyring_t *secring, - const unsigned armour, - pgp_memory_t *mem) -{ - return pgp_filter_keys_from_mem(io, - pubring, - secring, - NULL /* certring -> self certification */, - armour, - mem); -} - -/** - \ingroup HighLevel_KeyringRead - - \brief Frees keyring's contents (but not keyring itself) - - \param keyring Keyring whose data is to be freed - - \note This does not free keyring itself, just the memory alloc-ed in it. - */ -void -pgp_keyring_free(pgp_keyring_t *keyring) -{ - (void)free(keyring->keys); - keyring->keys = NULL; - keyring->keyc = keyring->keyvsize = 0; -} - -void -pgp_keyring_purge(pgp_keyring_t *keyring) -{ - pgp_key_t *keyp; - unsigned c = 0; - for (keyp = keyring->keys; c < keyring->keyc; c++, keyp++) { - pgp_key_free(keyp); - } - pgp_keyring_free(keyring); -} - -static unsigned -deletekey( pgp_keyring_t *keyring, pgp_key_t *key, unsigned from) -{ - /* 'from' is index of key to delete */ - - /* free key internals */ - pgp_key_free(key); - - /* decrement key count, vsize stays the same so no realloc needed */ - keyring->keyc--; - - /* Move following keys to fill the gap */ - for ( ; keyring && from < keyring->keyc; from += 1) { - memcpy(&keyring->keys[from], &keyring->keys[from+1], - sizeof(pgp_key_t)); - } - - return 1; -} - -unsigned key_id_match(const pgp_pubkey_t *key, const uint8_t *keyid, void *refidarg) -{ - uint8_t *refid = refidarg; - return (memcmp(keyid, refid, PGP_KEY_ID_SIZE) == 0); -} -/** - \ingroup HighLevel_KeyringFind - - \brief Finds key in keyring from its Key ID - - \param keyring Keyring to be searched - \param keyid ID of required key - - \return Pointer to key, if found; NULL, if not found - - \note This returns a pointer to the key inside the given keyring, - not a copy. Do not free it after use. - -*/ -pgp_key_t * -pgp_getkeybyid(pgp_io_t *io, const pgp_keyring_t *keyring, - const uint8_t *keyid, unsigned *from, - pgp_pubkey_t **pubkey, - pgp_seckey_t **seckey, - unsigned checkrevoke, - unsigned checkexpiry) -{ - uint8_t nullid[PGP_KEY_ID_SIZE]; - - (void) memset(nullid, 0x0, sizeof(nullid)); - for ( ; keyring && *from < keyring->keyc; *from += 1) { - pgp_key_t *key = &keyring->keys[*from]; - int32_t subkeyidx; - if (pgp_get_debug_level(__FILE__)) { - hexdump(io->errs, "keyring keyid", key->pubkeyid, PGP_KEY_ID_SIZE); - hexdump(io->errs, "keyid", keyid, PGP_KEY_ID_SIZE); - } - - subkeyidx = pgp_key_find_key_conds(key, &key_id_match, - (void*)keyid, NULL, NULL, - checkrevoke, checkexpiry); - - if (subkeyidx != -2) { - if (pubkey) { - *pubkey = key_get_pubkey_from_subidx(key, NULL, subkeyidx); - } - if (seckey) { - *seckey = key_get_seckey_from_subidx(key, NULL, subkeyidx); - } - return key; - } - } - return NULL; -} - -unsigned -pgp_deletekeybyid(pgp_io_t *io, pgp_keyring_t *keyring, - const uint8_t *keyid) -{ - unsigned from = 0; - pgp_key_t *key; - - if ((key = (pgp_key_t *)pgp_getkeybyid(io, keyring, keyid, - &from, NULL, NULL, 0, 0)) == NULL) { - return 0; - } - /* 'from' is now index of key to delete */ - - deletekey(keyring, key, from); - - return 1; -} - -/** - \ingroup HighLevel_KeyringFind - - \brief Finds key in keyring from its Key Fingerprint - - \param keyring Keyring to be searched - \param fpr fingerprint of required key - \param fpr length of required key - - \return Pointer to key, if found; NULL, if not found - - \note This returns a pointer to the key inside the given keyring, - not a copy. Do not free it after use. - -*/ - -pgp_key_t * -pgp_getkeybyfpr(pgp_io_t *io, const pgp_keyring_t *keyring, - const uint8_t *fpr, size_t length, - unsigned *from, - pgp_pubkey_t **pubkey, - unsigned checkrevoke, - unsigned checkexpiry) -{ - - for ( ; keyring && *from < keyring->keyc; *from += 1) { - pgp_key_t *key = &keyring->keys[*from]; - - pgp_fingerprint_t *kfp = &key->pubkeyfpr; - - if (kfp->length == length && - memcmp(kfp->fingerprint, fpr, length) == 0) { - - if(checkrevoke || checkexpiry){ - int32_t subkeyidx; - - subkeyidx = pgp_key_find_key_conds(key, - NULL, NULL, - NULL, NULL, - checkrevoke, checkexpiry); - - if (subkeyidx == -2) return NULL; - } - if (pubkey) { - *pubkey = &key->key.pubkey; - } - return key; - } - } - return NULL; -} - -unsigned -pgp_deletekeybyfpr(pgp_io_t *io, pgp_keyring_t *keyring, - const uint8_t *fpr, size_t length) -{ - unsigned from = 0; - pgp_key_t *key; - - if ((key = (pgp_key_t *)pgp_getkeybyfpr(io, keyring, fpr, length, - &from, NULL,0,0)) == NULL) { - return 0; - } - /* 'from' is now index of key to delete */ - - deletekey(keyring, key, from); - - return 1; -} - -#if 0 -/* convert a string keyid into a binary keyid */ -static void -str2keyid(const char *userid, uint8_t *keyid, size_t len) -{ - static const char *uppers = "0123456789ABCDEF"; - static const char *lowers = "0123456789abcdef"; - const char *hi; - const char *lo; - uint8_t hichar; - uint8_t lochar; - size_t j; - int i; - - for (i = 0, j = 0 ; j < len && userid[i] && userid[i + 1] ; i += 2, j++) { - if ((hi = strchr(uppers, userid[i])) == NULL) { - if ((hi = strchr(lowers, userid[i])) == NULL) { - break; - } - hichar = (uint8_t)(hi - lowers); - } else { - hichar = (uint8_t)(hi - uppers); - } - if ((lo = strchr(uppers, userid[i + 1])) == NULL) { - if ((lo = strchr(lowers, userid[i + 1])) == NULL) { - break; - } - lochar = (uint8_t)(lo - lowers); - } else { - lochar = (uint8_t)(lo - uppers); - } - keyid[j] = (hichar << 4) | (lochar); - } - keyid[j] = 0x0; -} -#endif - -/* return the next key which matches, starting searching at *from */ -#if 0 ////// -static const pgp_key_t * -getkeybyname(pgp_io_t *io, - const pgp_keyring_t *keyring, - const char *name, - unsigned *from) -{ - //const pgp_key_t *kp; - uint8_t **uidp; - unsigned i = 0; - pgp_key_t *keyp; - // unsigned savedstart; - regex_t r; - //uint8_t keyid[PGP_KEY_ID_SIZE + 1]; - size_t len; - - if (!keyring || !name || !from) { - return NULL; - } - len = strlen(name); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(io->outs, "[%u] name '%s', len %zu\n", - *from, name, len); - } - - /* first try name as a keyid */ - // (void) memset(keyid, 0x0, sizeof(keyid)); - // str2keyid(name, keyid, sizeof(keyid)); - // if (pgp_get_debug_level(__FILE__)) { - // hexdump(io->outs, "keyid", keyid, 4); - // } - // savedstart = *from; - // if ((kp = pgp_getkeybyid(io, keyring, keyid, from, - // NULL, NULL, 0, 0)) != NULL) { - // return kp; - // } - // *from = savedstart; - - if (pgp_get_debug_level(__FILE__) && name != NULL) { - (void) fprintf(io->outs, "regex match '%s' from %u\n", - name, *from); - } - /* match on full name or email address as a - - NOSUB only success/failure, no match content - - LITERAL ignore special chars in given string - - ICASE ignore case - */ - if (name != NULL) { - (void) regcomp(&r, name, REG_NOSUB | REG_LITERAL | REG_ICASE); - } - if(keyring->keys != NULL) - for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) { - uidp = keyp->uids; - if (name == NULL) { - return keyp; - } else { - for (i = 0 ; i < keyp->uidc; i++, uidp++) { - if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) { - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(io->outs, - "MATCHED keyid \"%s\" len %" PRIsize "u\n", - (char *) *uidp, len); - } - regfree(&r); - return keyp; - } - } - } - } - regfree(&r); - return NULL; -} -#endif ////// - -/** - \ingroup HighLevel_KeyringFind - - \brief Finds key from its User ID - - \param keyring Keyring to be searched - \param userid User ID of required key - - \return Pointer to Key, if found; NULL, if not found - - \note This returns a pointer to the key inside the keyring, not a - copy. Do not free it. - -*/ -#if 0 ////// -const pgp_key_t * -pgp_getkeybyname(pgp_io_t *io, - const pgp_keyring_t *keyring, - const char *name) -{ - unsigned from; - - from = 0; - return getkeybyname(io, keyring, name, &from); -} -#endif ////// - -#if 0 ////// -const pgp_key_t * -pgp_getnextkeybyname(pgp_io_t *io, - const pgp_keyring_t *keyring, - const char *name, - unsigned *n) -{ - return getkeybyname(io, keyring, name, n); -} -#endif ////// - -/* this interface isn't right - hook into callback for getting passphrase */ -#if 0 ////// -char * -pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase) -{ - pgp_output_t *output; - pgp_memory_t *mem; - char *cp; - - __PGP_USED(io); - pgp_setup_memory_write(&output, &mem, 128); - pgp_write_xfer_key(output, keydata, 1); - - /* TODO deal with passphrase again - pgp_write_xfer_seckey(output, keydata, passphrase, - strlen((char *)passphrase), 1); - */ - cp = netpgp_strdup(pgp_mem_data(mem)); - pgp_teardown_memory_write(output, mem); - return cp; -} -#endif ////// - -/* lowlevel add to keyring */ -int -pgp_keyring_add(pgp_keyring_t *dst, const pgp_key_t *src) -{ - pgp_key_t *key; - - EXPAND_ARRAY(dst, key); - key = &dst->keys[dst->keyc++]; - memcpy(key, src, sizeof(*key)); - return 1; -} - -pgp_key_t *pgp_ensure_pubkey( - pgp_keyring_t *keyring, - pgp_pubkey_t *pubkey, - uint8_t *pubkeyid) -{ - pgp_key_t *key; - unsigned c; - - if(keyring == NULL) return NULL; - - /* try to find key in keyring */ - for (c = 0; c < keyring->keyc; c += 1) { - if (memcmp(keyring->keys[c].pubkeyid, - pubkeyid, PGP_KEY_ID_SIZE) == 0) { - return &keyring->keys[c]; - } - } - - /* if key doesn't already exist in keyring, create it */ - EXPAND_ARRAY(keyring, key); - key = &keyring->keys[keyring->keyc++]; - (void) memset(key, 0x0, sizeof(*key)); - - /* fill in what we already know */ - key->type = PGP_PTAG_CT_PUBLIC_KEY; - pgp_pubkey_dup(&key->key.pubkey, pubkey); - (void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE); - pgp_fingerprint(&key->pubkeyfpr, pubkey, keyring->hashtype); - - return key; -} - -pgp_key_t *pgp_ensure_seckey( - pgp_keyring_t *keyring, - pgp_seckey_t *seckey, - uint8_t *pubkeyid) -{ - pgp_key_t *key; - unsigned c; - - if (keyring == NULL) return NULL; - - /* try to find key in keyring */ - for (c = 0; c < keyring->keyc; c += 1) { - if (memcmp(keyring->keys[c].pubkeyid, - pubkeyid, PGP_KEY_ID_SIZE) == 0) { - return &keyring->keys[c]; - } - } - - /* if key doesn't already exist in keyring, create it */ - EXPAND_ARRAY(keyring, key); - key = &keyring->keys[keyring->keyc++]; - (void) memset(key, 0x0, sizeof(*key)); - - /* fill in what we already know */ - key->type = PGP_PTAG_CT_SECRET_KEY; - pgp_seckey_dup(&key->key.seckey, seckey); - (void) memcpy(&key->pubkeyid, pubkeyid, PGP_KEY_ID_SIZE); - pgp_fingerprint(&key->pubkeyfpr, &seckey->pubkey, keyring->hashtype); - - return key; -} - -unsigned pgp_add_directsig( - pgp_key_t *key, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo) -{ - pgp_directsig_t *directsigp; - unsigned directsigidx; - - /* Detect duplicate direct sig */ - directsigp = key->directsigs; - for (directsigidx = 0 ; directsigidx < key->directsigc; - directsigidx++, directsigp++) - { - if( directsigp->packet.length == sigpkt->length && - memcmp(directsigp->packet.raw, sigpkt->raw, sigpkt->length) == 0) - { - /* signature already exist */ - return 1; - } - } - - - EXPAND_ARRAY(key, directsig); - directsigp = &key->directsigs[key->directsigc++]; - - copy_sig_info(&directsigp->siginfo, - siginfo); - pgp_copy_packet(&directsigp->packet, sigpkt); - - return 0; -} - -unsigned pgp_update_userid( - pgp_key_t *key, - const uint8_t *userid, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo) -{ - unsigned uididx = 0; - unsigned uidsigidx = 0; - uint8_t **uidp; - pgp_uidsig_t *uidsigp; - - /* Try to find identical userID */ - uidp = key->uids; - for (uididx = 0 ; uididx < key->uidc; uididx++, uidp++) - { - if (strcmp((char *)*uidp, (char *)userid) == 0) - { - /* Found one. check for duplicate uidsig */ - uidsigp = key->uidsigs; - for (uidsigidx = 0 ; uidsigidx < key->uidsigc; - uidsigidx++, uidsigp++) - { - if(uidsigp->uid == uididx && - uidsigp->packet.length == sigpkt->length && - memcmp(uidsigp->packet.raw, sigpkt->raw, - sigpkt->length) == 0) - { - /* signature already exists */ - return 1; - } - } - break; - } - } - - /* Add a new one if none found */ - if(uididx==key->uidc){ - EXPAND_ARRAY(key, uid); - uidp = &key->uids[key->uidc++]; - *uidp = NULL; - pgp_copy_userid(uidp, userid); - } - - /* Add uid sig info, pointing to that uid */ - EXPAND_ARRAY(key, uidsig); - uidsigp = &key->uidsigs[key->uidsigc++]; - uidsigp->uid = uididx; - - /* store sig info and packet */ - copy_sig_info(&uidsigp->siginfo, siginfo); - pgp_copy_packet(&uidsigp->packet, sigpkt); - - return 0; -} - -unsigned pgp_update_subkey( - pgp_key_t *key, - pgp_content_enum subkeytype, - pgp_keydata_key_t *subkey, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo) -{ - unsigned subkeyidx = 0; - unsigned subkeysigidx = 0; - pgp_subkey_t *subkeyp; - pgp_subkeysig_t *subkeysigp; - uint8_t subkeyid[PGP_KEY_ID_SIZE]; - - pgp_keyid(subkeyid, PGP_KEY_ID_SIZE, - (subkeytype == PGP_PTAG_CT_PUBLIC_KEY) ? - &subkey->pubkey: - &subkey->seckey.pubkey, PGP_HASH_SHA1); - - /* Try to find identical subkey ID */ - subkeyp = key->subkeys; - for (subkeyidx = 0 ; subkeyidx < key->subkeyc; subkeyidx++, subkeyp++) - { - if(memcmp(subkeyid, subkeyp->id, PGP_KEY_ID_SIZE) == 0 ) - { - /* Found same subkey. Detect duplicate sig */ - subkeysigp = key->subkeysigs; - for (subkeysigidx = 0 ; subkeysigidx < key->subkeysigc; - subkeysigidx++, subkeysigp++) - { - if(subkeysigp->subkey == subkeyidx && - subkeysigp->packet.length == sigpkt->length && - memcmp(subkeysigp->packet.raw, sigpkt->raw, - sigpkt->length) == 0) - { - /* signature already exists */ - return 1; - } - } - - break; - } - } - /* Add a new one if none found */ - if(subkeyidx==key->subkeyc){ - if(subkeytype == PGP_PTAG_CT_PUBLIC_KEY && - key->type != PGP_PTAG_CT_PUBLIC_KEY){ - /* cannot create secret subkey from public */ - /* and may not insert public subkey in seckey */ - return 1; - } - - EXPAND_ARRAY(key, subkey); - subkeyp = &key->subkeys[key->subkeyc++]; - /* copy subkey material */ - if(key->type == PGP_PTAG_CT_PUBLIC_KEY) { - pgp_pubkey_dup(&subkeyp->key.pubkey, - (subkeytype == PGP_PTAG_CT_PUBLIC_KEY) ? - &subkey->pubkey: - &subkey->seckey.pubkey); - } else { - pgp_seckey_dup(&subkeyp->key.seckey, &subkey->seckey); - } - /* copy subkeyID */ - memcpy(subkeyp->id, subkeyid, PGP_KEY_ID_SIZE); - } - - /* Add subkey sig info, pointing to that subkey */ - EXPAND_ARRAY(key, subkeysig); - subkeysigp = &key->subkeysigs[key->subkeysigc++]; - subkeysigp->subkey = subkeyidx; - - /* store sig info and packet */ - copy_sig_info(&subkeysigp->siginfo, - siginfo); - pgp_copy_packet(&subkeysigp->packet, sigpkt); - - return 0; -} - -/* append one keyring to another */ -int -pgp_append_keyring(pgp_keyring_t *keyring, pgp_keyring_t *newring) -{ - unsigned i; - - for (i = 0 ; i < newring->keyc ; i++) { - EXPAND_ARRAY(keyring, key); - (void) memcpy(&keyring->keys[keyring->keyc], &newring->keys[i], - sizeof(newring->keys[i])); - keyring->keyc += 1; - } - return 1; -} diff --git a/netpgp/misc.c b/netpgp/misc.c deleted file mode 100644 index 8492be3932b40b3279e29f81e6cac163406ae1e2..0000000000000000000000000000000000000000 --- a/netpgp/misc.c +++ /dev/null @@ -1,1264 +0,0 @@ -/*- - * Copyright (c) 2009,2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <ctype.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_OPENSSL_RAND_H -#include <openssl/rand.h> -#endif - -#include "netpgp/errors.h" -#include "netpgp/packet.h" -#include "netpgp/crypto.h" -#include "netpgp/create.h" -#include "netpgp/packet-parse.h" -#include "netpgp/packet-show.h" -#include "netpgp/signature.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/memory.h" -#include "netpgp/readerwriter.h" -#include "netpgp/version.h" -#include "netpgp/netpgpdigest.h" - -#ifdef WIN32 -#define vsnprintf _vsnprintf -#endif - -/** \file - * \brief Error Handling - */ -#define ERRNAME(code) { code, #code } - -static pgp_errcode_name_map_t errcode_name_map[] = { - ERRNAME(PGP_E_OK), - ERRNAME(PGP_E_FAIL), - ERRNAME(PGP_E_SYSTEM_ERROR), - ERRNAME(PGP_E_UNIMPLEMENTED), - - ERRNAME(PGP_E_R), - ERRNAME(PGP_E_R_READ_FAILED), - ERRNAME(PGP_E_R_EARLY_EOF), - ERRNAME(PGP_E_R_BAD_FORMAT), - ERRNAME(PGP_E_R_UNCONSUMED_DATA), - - ERRNAME(PGP_E_W), - ERRNAME(PGP_E_W_WRITE_FAILED), - ERRNAME(PGP_E_W_WRITE_TOO_SHORT), - - ERRNAME(PGP_E_P), - ERRNAME(PGP_E_P_NOT_ENOUGH_DATA), - ERRNAME(PGP_E_P_UNKNOWN_TAG), - ERRNAME(PGP_E_P_PACKET_CONSUMED), - ERRNAME(PGP_E_P_MPI_FORMAT_ERROR), - - ERRNAME(PGP_E_C), - - ERRNAME(PGP_E_V), - ERRNAME(PGP_E_V_BAD_SIGNATURE), - ERRNAME(PGP_E_V_NO_SIGNATURE), - ERRNAME(PGP_E_V_UNKNOWN_SIGNER), - - ERRNAME(PGP_E_ALG), - ERRNAME(PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG), - ERRNAME(PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG), - ERRNAME(PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG), - ERRNAME(PGP_E_ALG_UNSUPPORTED_HASH_ALG), - - ERRNAME(PGP_E_PROTO), - ERRNAME(PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT), - ERRNAME(PGP_E_PROTO_UNKNOWN_SS), - ERRNAME(PGP_E_PROTO_CRITICAL_SS_IGNORED), - ERRNAME(PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN), - ERRNAME(PGP_E_PROTO_BAD_SIGNATURE_VRSN), - ERRNAME(PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN), - ERRNAME(PGP_E_PROTO_BAD_PKSK_VRSN), - ERRNAME(PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN), - ERRNAME(PGP_E_PROTO_BAD_SK_CHECKSUM), - - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -/** - * \ingroup Core_Errors - * \brief returns error code name - * \param errcode - * \return error code name or "Unknown" - */ -const char * -pgp_errcode(const pgp_errcode_t errcode) -{ - return (pgp_str_from_map((int) errcode, - (pgp_map_t *) errcode_name_map)); -} - -/* generic grab new storage function */ -void * -pgp_new(size_t size) -{ - void *vp; - - if ((vp = calloc(1, size)) == NULL) { - (void) fprintf(stderr, - "allocation failure for %" PRIsize "u bytes", size); - } - return vp; -} - -/** - * \ingroup Core_Errors - * \brief Pushes the given error on the given errorstack - * \param errstack Error stack to use - * \param errcode Code of error to push - * \param sys_errno System errno (used if errcode=PGP_E_SYSTEM_ERROR) - * \param file Source filename where error occurred - * \param line Line in source file where error occurred - * \param fmt Comment - * - */ - -void -pgp_push_error(pgp_error_t **errstack, pgp_errcode_t errcode, - int sys_errno, const char *file, int line, const char *fmt,...) -{ - /* first get the varargs and generate the comment */ - pgp_error_t *err; - unsigned maxbuf = 128; - va_list args; - char *comment; - - if ((comment = calloc(1, maxbuf + 1)) == NULL) { - (void) fprintf(stderr, "calloc comment failure\n"); - return; - } - - va_start(args, fmt); - vsnprintf(comment, maxbuf + 1, fmt, args); - va_end(args); - - /* alloc a new error and add it to the top of the stack */ - - if ((err = calloc(1, sizeof(*err))) == NULL) { - (void) fprintf(stderr, "calloc comment failure\n"); - return; - } - - err->next = *errstack; - *errstack = err; - - /* fill in the details */ - err->errcode = errcode; - err->sys_errno = sys_errno; - err->file = file; - err->line = line; - - err->comment = comment; -} - -/** -\ingroup Core_Errors -\brief print this error -\param err Error to print -*/ -void -pgp_print_error(pgp_error_t *err) -{ - printf("%s:%d: ", err->file, err->line); - if (err->errcode == PGP_E_SYSTEM_ERROR) { - printf("system error %d returned from %s()\n", err->sys_errno, - err->comment); - } else { - printf("%s, %s\n", pgp_errcode(err->errcode), err->comment); - } -} - -/** -\ingroup Core_Errors -\brief Print all errors on stack -\param errstack Error stack to print -*/ -void -pgp_print_errors(pgp_error_t *errstack) -{ - pgp_error_t *err; - - for (err = errstack; err != NULL; err = err->next) { - pgp_print_error(err); - } -} - -/** -\ingroup Core_Errors -\brief Return 1 if given error is present anywhere on stack -\param errstack Error stack to check -\param errcode Error code to look for -\return 1 if found; else 0 -*/ -int -pgp_has_error(pgp_error_t *errstack, pgp_errcode_t errcode) -{ - pgp_error_t *err; - - for (err = errstack; err != NULL; err = err->next) { - if (err->errcode == errcode) { - return 1; - } - } - return 0; -} - -/** -\ingroup Core_Errors -\brief Frees all errors on stack -\param errstack Error stack to free -*/ -void -pgp_free_errors(pgp_error_t *errstack) -{ - pgp_error_t *next; - - while (errstack != NULL) { - next = errstack->next; - free(errstack->comment); - free(errstack); - errstack = next; - } -} - -/* hash a 32-bit integer */ -static int -hash_uint32(pgp_hash_t *hash, uint32_t n) -{ - uint8_t ibuf[4]; - - ibuf[0] = (uint8_t)(n >> 24) & 0xff; - ibuf[1] = (uint8_t)(n >> 16) & 0xff; - ibuf[2] = (uint8_t)(n >> 8) & 0xff; - ibuf[3] = (uint8_t)n & 0xff; - (*hash->add)(hash, (const uint8_t *)(void *)ibuf, (unsigned)sizeof(ibuf)); - return sizeof(ibuf); -} - -/* hash a string - first length, then string itself */ -static int -hash_string(pgp_hash_t *hash, const uint8_t *buf, uint32_t len) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "hash_string", buf, len); - } - hash_uint32(hash, len); - (*hash->add)(hash, buf, len); - return (int)(sizeof(len) + len); -} - -/* hash a bignum, possibly padded - first length, then string itself */ -static int -hash_bignum(pgp_hash_t *hash, BIGNUM *bignum) -{ - uint8_t *bn; - size_t len; - int padbyte; - - if (BN_is_zero(bignum)) { - hash_uint32(hash, 0); - return sizeof(len); - } - if ((len = (size_t) BN_num_bytes(bignum)) < 1) { - (void) fprintf(stderr, "hash_bignum: bad size\n"); - return 0; - } - if ((bn = calloc(1, len)) == NULL) { - (void) fprintf(stderr, "hash_bignum: bad bn alloc\n"); - return 0; - } - BN_bn2bin(bignum, bn + 1); - bn[0] = 0x0; - padbyte = (bn[1] & 0x80) ? 1 : 0; - hash_string(hash, bn + 1 - padbyte, (unsigned)(len + padbyte)); - free(bn); - return (int)(sizeof(len) + len + padbyte); -} - -/** \file - */ - -/** - * \ingroup Core_Keys - * \brief Calculate a public key fingerprint. - * \param fp Where to put the calculated fingerprint - * \param key The key for which the fingerprint is calculated - */ -int -pgp_fingerprint(pgp_fingerprint_t *fp, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype) -{ - pgp_memory_t *mem; - pgp_hash_t hash; - const char *type; - uint32_t len; - - mem = pgp_memory_new(); - if (key->version == 2 || key->version == 3) { - if (key->alg != PGP_PKA_RSA && - key->alg != PGP_PKA_RSA_ENCRYPT_ONLY && - key->alg != PGP_PKA_RSA_SIGN_ONLY) { - (void) fprintf(stderr, - "pgp_fingerprint: bad algorithm\n"); - return 0; - } - pgp_hash_md5(&hash); - if (!hash.init(&hash)) { - (void) fprintf(stderr, - "pgp_fingerprint: bad md5 alloc\n"); - return 0; - } - hash_bignum(&hash, key->key.rsa.n); - hash_bignum(&hash, key->key.rsa.e); - fp->length = hash.finish(&hash, fp->fingerprint); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "v2/v3 fingerprint", fp->fingerprint, fp->length); - } - } else if (hashtype == PGP_HASH_MD5) { - pgp_hash_md5(&hash); - if (!hash.init(&hash)) { - (void) fprintf(stderr, - "pgp_fingerprint: bad md5 alloc\n"); - return 0; - } - type = (key->alg == PGP_PKA_RSA) ? "ssh-rsa" : "ssh-dss"; - hash_string(&hash, (const uint8_t *)(const void *)type, (unsigned)strlen(type)); - switch(key->alg) { - case PGP_PKA_RSA: - hash_bignum(&hash, key->key.rsa.e); - hash_bignum(&hash, key->key.rsa.n); - break; - case PGP_PKA_DSA: - hash_bignum(&hash, key->key.dsa.p); - hash_bignum(&hash, key->key.dsa.q); - hash_bignum(&hash, key->key.dsa.g); - hash_bignum(&hash, key->key.dsa.y); - break; - default: - break; - } - fp->length = hash.finish(&hash, fp->fingerprint); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "md5 fingerprint", fp->fingerprint, fp->length); - } - } else { - pgp_build_pubkey(mem, key, 0); - pgp_hash_sha1(&hash); - if (!hash.init(&hash)) { - (void) fprintf(stderr, - "pgp_fingerprint: bad sha1 alloc\n"); - return 0; - } - len = (unsigned)pgp_mem_len(mem); - pgp_hash_add_int(&hash, 0x99, 1); - pgp_hash_add_int(&hash, len, 2); - hash.add(&hash, pgp_mem_data(mem), len); - fp->length = hash.finish(&hash, fp->fingerprint); - pgp_memory_free(mem); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha1 fingerprint", fp->fingerprint, fp->length); - } - } - return 1; -} - -/** - * \ingroup Core_Keys - * \brief Calculate the Key ID from the public key. - * \param keyid Space for the calculated ID to be stored - * \param key The key for which the ID is calculated - */ - -int -pgp_keyid(uint8_t *keyid, const size_t idlen, const pgp_pubkey_t *key, pgp_hash_alg_t hashtype) -{ - pgp_fingerprint_t finger; - - if (key->version == 2 || key->version == 3) { - unsigned n; - uint8_t bn[NETPGP_BUFSIZ]; - - n = (unsigned) BN_num_bytes(key->key.rsa.n); - if (n > sizeof(bn)) { - (void) fprintf(stderr, "pgp_keyid: bad num bytes\n"); - return 0; - } - if (key->alg != PGP_PKA_RSA && - key->alg != PGP_PKA_RSA_ENCRYPT_ONLY && - key->alg != PGP_PKA_RSA_SIGN_ONLY) { - (void) fprintf(stderr, "pgp_keyid: bad algorithm\n"); - return 0; - } - BN_bn2bin(key->key.rsa.n, bn); - (void) memcpy(keyid, bn + n - idlen, idlen); - } else { - pgp_fingerprint(&finger, key, hashtype); - (void) memcpy(keyid, - finger.fingerprint + finger.length - idlen, - idlen); - } - return 1; -} - -/** -\ingroup Core_Hashes -\brief Add to the hash -\param hash Hash to add to -\param n Int to add -\param length Length of int in bytes -*/ -void -pgp_hash_add_int(pgp_hash_t *hash, unsigned n, unsigned length) -{ - uint8_t c; - - while (length--) { - c = n >> (length * 8); - hash->add(hash, &c, 1); - } -} - -/** -\ingroup Core_Hashes -\brief Setup hash for given hash algorithm -\param hash Hash to set up -\param alg Hash algorithm to use -*/ -unsigned -pgp_hash_any(pgp_hash_t *hash, pgp_hash_alg_t alg) -{ - switch (alg) { - case PGP_HASH_MD5: - pgp_hash_md5(hash); - break; - - case PGP_HASH_SHA1: - pgp_hash_sha1(hash); - break; - - case PGP_HASH_SHA256: - pgp_hash_sha256(hash); - break; - - case PGP_HASH_SHA384: - pgp_hash_sha384(hash); - break; - - case PGP_HASH_SHA512: - pgp_hash_sha512(hash); - break; - - case PGP_HASH_SHA224: - pgp_hash_sha224(hash); - break; - - default: - (void) fprintf(stderr, "pgp_hash_any: bad algorithm\n"); - return 0; - } - return 1; -} - -/** -\ingroup Core_Hashes -\brief Returns size of hash for given hash algorithm -\param alg Hash algorithm to use -\return Size of hash algorithm in bytes -*/ -unsigned -pgp_hash_size(pgp_hash_alg_t alg) -{ - switch (alg) { - case PGP_HASH_MD5: - return 16; - - case PGP_HASH_SHA1: - return 20; - - case PGP_HASH_SHA256: - return 32; - - case PGP_HASH_SHA224: - return 28; - - case PGP_HASH_SHA512: - return 64; - - case PGP_HASH_SHA384: - return 48; - - default: - (void) fprintf(stderr, "pgp_hash_size: bad algorithm\n"); - } - - return 0; -} - -/** -\ingroup Core_Hashes -\brief Returns hash enum corresponding to given string -\param hash Text name of hash algorithm i.e. "SHA1" -\returns Corresponding enum i.e. PGP_HASH_SHA1 -*/ -pgp_hash_alg_t -pgp_str_to_hash_alg(const char *hash) -{ - if (hash == NULL) { - return PGP_DEFAULT_HASH_ALGORITHM; - } - if (netpgp_strcasecmp(hash, "SHA1") == 0) { - return PGP_HASH_SHA1; - } - if (netpgp_strcasecmp(hash, "MD5") == 0) { - return PGP_HASH_MD5; - } - if (netpgp_strcasecmp(hash, "SHA256") == 0) { - return PGP_HASH_SHA256; - } - /* - if (netpgp_strcasecmp(hash,"SHA224") == 0) { - return PGP_HASH_SHA224; - } - */ - if (netpgp_strcasecmp(hash, "SHA512") == 0) { - return PGP_HASH_SHA512; - } - if (netpgp_strcasecmp(hash, "SHA384") == 0) { - return PGP_HASH_SHA384; - } - return PGP_HASH_UNKNOWN; -} - -/** -\ingroup Core_Hashes -\brief Hash given data -\param out Where to write the hash -\param alg Hash algorithm to use -\param in Data to hash -\param length Length of data -\return Size of hash created -*/ -unsigned -pgp_hash(uint8_t *out, pgp_hash_alg_t alg, const void *in, size_t length) -{ - pgp_hash_t hash; - - pgp_hash_any(&hash, alg); - if (!hash.init(&hash)) { - (void) fprintf(stderr, "pgp_hash: bad alloc\n"); - /* we'll just continue here - don't want to return a 0 hash */ - /* XXX - agc - no way to return failure */ - } - hash.add(&hash, in, (unsigned)length); - return hash.finish(&hash, out); -} - -/** -\ingroup Core_Hashes -\brief Calculate hash for MDC packet -\param preamble Preamble to hash -\param sz_preamble Size of preamble -\param plaintext Plaintext to hash -\param sz_plaintext Size of plaintext -\param hashed Resulting hash -*/ -void -pgp_calc_mdc_hash(const uint8_t *preamble, - const size_t sz_preamble, - const uint8_t *plaintext, - const unsigned sz_plaintext, - uint8_t *hashed) -{ - pgp_hash_t hash; - uint8_t c; - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "preamble", preamble, sz_preamble); - hexdump(stderr, "plaintext", plaintext, sz_plaintext); - } - /* init */ - pgp_hash_any(&hash, PGP_HASH_SHA1); - if (!hash.init(&hash)) { - (void) fprintf(stderr, "pgp_calc_mdc_hash: bad alloc\n"); - /* we'll just continue here - it will die anyway */ - /* agc - XXX - no way to return failure */ - } - - /* preamble */ - hash.add(&hash, preamble, (unsigned)sz_preamble); - /* plaintext */ - hash.add(&hash, plaintext, sz_plaintext); - /* MDC packet tag */ - c = MDC_PKT_TAG; - hash.add(&hash, &c, 1); - /* MDC packet len */ - c = PGP_SHA1_HASH_SIZE; - hash.add(&hash, &c, 1); - - /* finish */ - hash.finish(&hash, hashed); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "hashed", hashed, PGP_SHA1_HASH_SIZE); - } -} - -/** -\ingroup HighLevel_Supported -\brief Is this Hash Algorithm supported? -\param hash_alg Hash Algorithm to check -\return 1 if supported; else 0 -*/ -unsigned -pgp_is_hash_alg_supported(const pgp_hash_alg_t *hash_alg) -{ - switch (*hash_alg) { - case PGP_HASH_MD5: - case PGP_HASH_SHA1: - case PGP_HASH_SHA256: - return 1; - - default: - return 0; - } -} - -/* structure to map string to cipher def */ -typedef struct str2cipher_t { - const char *s; /* cipher name */ - pgp_symm_alg_t i; /* cipher def */ -} str2cipher_t; - -static str2cipher_t str2cipher[] = { - { "cast5", PGP_SA_CAST5 }, - { "idea", PGP_SA_IDEA }, - { "aes128", PGP_SA_AES_128 }, - { "aes256", PGP_SA_AES_256 }, - { "camellia128", PGP_SA_CAMELLIA_128 }, - { "camellia256", PGP_SA_CAMELLIA_256 }, - { "tripledes", PGP_SA_TRIPLEDES }, - { NULL, 0 } -}; - -/* convert from a string to a cipher definition */ -pgp_symm_alg_t -pgp_str_to_cipher(const char *cipher) -{ - str2cipher_t *sp; - - for (sp = str2cipher ; cipher && sp->s ; sp++) { - if (netpgp_strcasecmp(cipher, sp->s) == 0) { - return sp->i; - } - } - return PGP_SA_DEFAULT_CIPHER; -} - -void -pgp_random(void *dest, size_t length) -{ - RAND_bytes(dest, (int)length); -} - -/** -\ingroup HighLevel_Memory -\brief Memory to initialise -\param mem memory to initialise -\param needed Size to initialise to -*/ -void -pgp_memory_init(pgp_memory_t *mem, size_t needed) -{ - uint8_t *temp; - - mem->length = 0; - if (mem->buf) { - if (mem->allocated < needed) { - if ((temp = realloc(mem->buf, needed)) == NULL) { - (void) fprintf(stderr, "pgp_memory_init: bad alloc\n"); - } else { - mem->buf = temp; - mem->allocated = needed; - } - } - } else { - if ((mem->buf = calloc(1, needed)) == NULL) { - (void) fprintf(stderr, "pgp_memory_init: bad alloc\n"); - } else { - mem->allocated = needed; - } - } -} - -/** -\ingroup HighLevel_Memory -\brief Pad memory to required length -\param mem Memory to use -\param length New size -*/ -void -pgp_memory_pad(pgp_memory_t *mem, size_t length) -{ - uint8_t *temp; - - if (mem->allocated < mem->length) { - (void) fprintf(stderr, "pgp_memory_pad: bad alloc in\n"); - return; - } - if (mem->allocated < mem->length + length) { - mem->allocated = mem->allocated * 2 + length; - temp = realloc(mem->buf, mem->allocated); - if (temp == NULL) { - (void) fprintf(stderr, "pgp_memory_pad: bad alloc\n"); - } else { - mem->buf = temp; - } - } - if (mem->allocated < mem->length + length) { - (void) fprintf(stderr, "pgp_memory_pad: bad alloc out\n"); - } -} - -/** -\ingroup HighLevel_Memory -\brief Add data to memory -\param mem Memory to which to add -\param src Data to add -\param length Length of data to add -*/ -void -pgp_memory_add(pgp_memory_t *mem, const uint8_t *src, size_t length) -{ - pgp_memory_pad(mem, length); - (void) memcpy(mem->buf + mem->length, src, length); - mem->length += length; -} - -/* XXX: this could be refactored via the writer, but an awful lot of */ -/* hoops to jump through for 2 lines of code! */ -void -pgp_memory_place_int(pgp_memory_t *mem, unsigned offset, unsigned n, - size_t length) -{ - if (mem->allocated < offset + length) { - (void) fprintf(stderr, - "pgp_memory_place_int: bad alloc\n"); - } else { - while (length-- > 0) { - mem->buf[offset++] = n >> (length * 8); - } - } -} - -/** - * \ingroup HighLevel_Memory - * \brief Retains allocated memory and set length of stored data to zero. - * \param mem Memory to clear - * \sa pgp_memory_release() - * \sa pgp_memory_free() - */ -void -pgp_memory_clear(pgp_memory_t *mem) -{ - mem->length = 0; -} - -/** -\ingroup HighLevel_Memory -\brief Free memory and associated data -\param mem Memory to free -\note This does not free mem itself -\sa pgp_memory_clear() -\sa pgp_memory_free() -*/ -void -pgp_memory_release(pgp_memory_t *mem) -{ - if (mem->mmapped) { - (void) munmap(mem->buf, mem->length); - } else { - free(mem->buf); - } - mem->buf = NULL; - mem->length = 0; -} - -void -pgp_memory_make_packet(pgp_memory_t *out, pgp_content_enum tag) -{ - size_t extra; - - extra = (out->length < 192) ? 1 : (out->length < 8192 + 192) ? 2 : 5; - pgp_memory_pad(out, extra + 1); - memmove(out->buf + extra + 1, out->buf, out->length); - - out->buf[0] = PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT | tag; - - if (out->length < 192) { - out->buf[1] = (uint8_t)out->length; - } else if (out->length < 8192 + 192) { - out->buf[1] = (uint8_t)((out->length - 192) >> 8) + 192; - out->buf[2] = (uint8_t)(out->length - 192); - } else { - out->buf[1] = 0xff; - out->buf[2] = (uint8_t)(out->length >> 24); - out->buf[3] = (uint8_t)(out->length >> 16); - out->buf[4] = (uint8_t)(out->length >> 8); - out->buf[5] = (uint8_t)(out->length); - } - - out->length += extra + 1; -} - -/** - \ingroup HighLevel_Memory - \brief Create a new zeroed pgp_memory_t - \return Pointer to new pgp_memory_t - \note Free using pgp_memory_free() after use. - \sa pgp_memory_free() -*/ - -pgp_memory_t * -pgp_memory_new(void) -{ - return calloc(1, sizeof(pgp_memory_t)); -} - -/** - \ingroup HighLevel_Memory - \brief Free memory ptr and associated memory - \param mem Memory to be freed - \sa pgp_memory_release() - \sa pgp_memory_clear() -*/ - -void -pgp_memory_free(pgp_memory_t *mem) -{ - pgp_memory_release(mem); - free(mem); -} - -/** - \ingroup HighLevel_Memory - \brief Get length of data stored in pgp_memory_t struct - \return Number of bytes in data -*/ -size_t -pgp_mem_len(const pgp_memory_t *mem) -{ - return mem->length; -} - -/** - \ingroup HighLevel_Memory - \brief Get data stored in pgp_memory_t struct - \return Pointer to data -*/ -void * -pgp_mem_data(pgp_memory_t *mem) -{ - return mem->buf; -} - -/* read a gile into an pgp_memory_t */ -int -pgp_mem_readfile(pgp_memory_t *mem, const char *f) -{ - struct stat st; - FILE *fp; - int cc; - - if ((fp = fopen(f, "rb")) == NULL) { - (void) fprintf(stderr, - "pgp_mem_readfile: can't open \"%s\"\n", f); - return 0; - } - (void) fstat(fileno(fp), &st); - mem->allocated = (size_t)st.st_size; - mem->buf = mmap(NULL, mem->allocated, PROT_READ, - MAP_PRIVATE | MAP_FILE, fileno(fp), 0); - if (mem->buf == MAP_FAILED) { - /* mmap failed for some reason - try to allocate memory */ - if ((mem->buf = calloc(1, mem->allocated)) == NULL) { - (void) fprintf(stderr, "pgp_mem_readfile: calloc\n"); - (void) fclose(fp); - return 0; - } - /* read into contents of mem */ - for (mem->length = 0 ; - (cc = (int)read(fileno(fp), &mem->buf[mem->length], - (size_t)(mem->allocated - mem->length))) > 0 ; - mem->length += (size_t)cc) { - } - } else { - mem->length = mem->allocated; - mem->mmapped = 1; - } - (void) fclose(fp); - return (mem->allocated == mem->length); -} - -typedef struct { - uint16_t sum; -} sum16_t; - - -/** - * Searches the given map for the given type. - * Returns a human-readable descriptive string if found, - * returns NULL if not found - * - * It is the responsibility of the calling function to handle the - * error case sensibly (i.e. don't just print out the return string. - * - */ -static const char * -str_from_map_or_null(int type, pgp_map_t *map) -{ - pgp_map_t *row; - - for (row = map; row->string != NULL; row++) { - if (row->type == type) { - return row->string; - } - } - return NULL; -} - -/** - * \ingroup Core_Print - * - * Searches the given map for the given type. - * Returns a readable string if found, "Unknown" if not. - */ - -const char * -pgp_str_from_map(int type, pgp_map_t *map) -{ - const char *str; - - str = str_from_map_or_null(type, map); - return (str) ? str : "Unknown"; -} - -#define LINELEN 16 - -/* show hexadecimal/ascii dump */ -void -hexdump(FILE *fp, const char *header, const uint8_t *src, size_t length) -{ - size_t i; - char line[LINELEN + 1]; - - (void) fprintf(fp, "%s%s", (header) ? header : "", (header) ? "\n" : ""); - (void) fprintf(fp, "[%" PRIsize "u char%s]\n", length, (length == 1) ? "" : "s"); - for (i = 0 ; i < length ; i++) { - if (i % LINELEN == 0) { - (void) fprintf(fp, "%.5" PRIsize "u | ", i); - } - (void) fprintf(fp, "%.02x ", (uint8_t)src[i]); - line[i % LINELEN] = (isprint(src[i])) ? src[i] : '.'; - if (i % LINELEN == LINELEN - 1) { - line[LINELEN] = 0x0; - (void) fprintf(fp, " | %s\n", line); - } - } - if (i % LINELEN != 0) { - for ( ; i % LINELEN != 0 ; i++) { - (void) fprintf(fp, " "); - line[i % LINELEN] = ' '; - } - line[LINELEN] = 0x0; - (void) fprintf(fp, " | %s\n", line); - } -} - -/** - * \ingroup HighLevel_Functions - * \brief Closes down OpenPGP::SDK. - * - * Close down OpenPGP:SDK, release any resources under the control of - * the library. - */ - -void -pgp_finish(void) -{ - pgp_crypto_finish(); -} - -static int -sum16_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - const uint8_t *dest = dest_; - sum16_t *arg = pgp_reader_get_arg(readinfo); - int r; - int n; - - r = pgp_stacked_read(stream, dest_, length, errors, readinfo, cbinfo); - if (r < 0) { - return r; - } - for (n = 0; n < r; ++n) { - arg->sum = (arg->sum + dest[n]) & 0xffff; - } - return r; -} - -static void -sum16_destroyer(pgp_reader_t *readinfo) -{ - free(pgp_reader_get_arg(readinfo)); -} - -/** - \ingroup Internal_Readers_Sum16 - \param stream Parse settings -*/ - -void -pgp_reader_push_sum16(pgp_stream_t *stream) -{ - sum16_t *arg; - - if ((arg = calloc(1, sizeof(*arg))) == NULL) { - (void) fprintf(stderr, "pgp_reader_push_sum16: bad alloc\n"); - } else { - pgp_reader_push(stream, sum16_reader, sum16_destroyer, arg); - } -} - -/** - \ingroup Internal_Readers_Sum16 - \param stream Parse settings - \return sum -*/ -uint16_t -pgp_reader_pop_sum16(pgp_stream_t *stream) -{ - uint16_t sum; - sum16_t *arg; - - arg = pgp_reader_get_arg(pgp_readinfo(stream)); - sum = arg->sum; - pgp_reader_pop(stream); - free(arg); - return sum; -} - -/* small useful functions for setting the file-level debugging levels */ -/* if the debugv list contains the filename in question, we're debugging it */ -#if 0 ////// -enum { - MAX_DEBUG_NAMES = 32 -}; - -static int debugc; -static char *debugv[MAX_DEBUG_NAMES]; -#endif ////// - -/* set the debugging level per filename */ -#if 0 ////// -int -pgp_set_debug_level(const char *f) -{ - const char *name; - int i; - - if (f == NULL) { - f = "all"; - } - if ((name = strrchr(f, '/')) == NULL) { - name = f; - } else { - name += 1; - } - for (i = 0; i < debugc && i < MAX_DEBUG_NAMES; i++) { - if (strcmp(debugv[i], name) == 0) { - return 1; - } - } - if (i == MAX_DEBUG_NAMES) { - return 0; - } - debugv[debugc++] = netpgp_strdup(name); - return 1; -} -#endif ////// - -/* get the debugging level per filename */ -int -pgp_get_debug_level(const char *f) -{ -#if 0 ////// - const char *name; - int i; - - if ((name = strrchr(f, '/')) == NULL) { - name = f; - } else { - name += 1; - } - for (i = 0; i < debugc; i++) { - if (strcmp(debugv[i], "all") == 0 || - strcmp(debugv[i], name) == 0) { - return 1; - } - } -#endif ////// - return 0; -} - -/* return the version for the library */ -#if 0 ////// -const char * -pgp_get_info(const char *type) -{ - if (strcmp(type, "version") == 0) { - return NETPGP_VERSION_STRING; - } - if (strcmp(type, "maintainer") == 0) { - return NETPGP_MAINTAINER; - } - return "[unknown]"; -} -#endif ////// - -/* local version of asprintf so we don't have to play autoconf games */ -int -pgp_asprintf(char **ret, const char *fmt, ...) -{ - va_list args; - char buf[120 * 1024]; /* XXX - "huge" buffer on stack */ - int cc; - - va_start(args, fmt); - cc = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if ((*ret = calloc(1, (size_t)(cc + 1))) == NULL) { - *ret = NULL; - return -1; - } - (void) memcpy(*ret, buf, (size_t)cc); - (*ret)[cc] = 0x0; - return cc; -} - -void -netpgp_log(const char *fmt, ...) -{ - va_list vp; - time_t t; - char buf[BUFSIZ * 2]; - int cc; - - (void) time(&t); - cc = snprintf(buf, sizeof(buf), "%.24s: netpgp: ", ctime(&t)); - va_start(vp, fmt); - (void) vsnprintf(&buf[cc], sizeof(buf) - (size_t)cc, fmt, vp); - va_end(vp); - /* do something with message */ - /* put into log buffer? */ -} - -/* portable replacement for strdup(3) */ -char * -netpgp_strdup(const char *s) -{ - size_t len; - char *cp; - - len = strlen(s); - if ((cp = calloc(1, len + 1)) != NULL) { - (void) memcpy(cp, s, len); - cp[len] = 0x0; - } - return cp; -} - -/* portable replacement for strcasecmp(3) */ -int -netpgp_strcasecmp(const char *s1, const char *s2) -{ - int n; - - for (n = 0 ; *s1 && *s2 && (n = tolower((uint8_t)*s1) - tolower((uint8_t)*s2)) == 0 ; s1++, s2++) { - } - return n; -} diff --git a/netpgp/netpgp-extra.h b/netpgp/netpgp-extra.h deleted file mode 100644 index 15b5353a4ea717e6e40f0285754fcb8c3d7fbf1a..0000000000000000000000000000000000000000 --- a/netpgp/netpgp-extra.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __NETPGP_EXTRA_H__ -#define __NETPGP_EXTRA_H__ - -#include "netpgp/config-netpgp.h" -#include "netpgp/packet-parse.h" -#include "netpgp/errors.h" -#include "netpgp/defs.h" -#include "netpgp/crypto.h" -#include "netpgp/create.h" -#include "netpgp/signature.h" -#include "netpgp/readerwriter.h" -#include "netpgp/validate.h" -unsigned rsa_generate_keypair(pgp_key_t *keydata, const int numbits, const unsigned long e, const char *hashalg, const char *cipher); - -#endif // __NETPGP_EXTRA_H__ diff --git a/netpgp/netpgp/config-netpgp.h b/netpgp/netpgp/config-netpgp.h deleted file mode 100644 index 610b8eacd306f1b4ab804efc62ccf2251f66bfbb..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/config-netpgp.h +++ /dev/null @@ -1,201 +0,0 @@ - -#ifndef __CONFIG_NETPGP_H__ -#define __CONFIG_NETPGP_H__ - - -/* src/lib/config.h. Generated from config.h.in by configure. */ -/* src/lib/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the <bzlib.h> header file. */ -/*#undef HAVE_BZLIB_H 1*/ /* EDIT BY MR */ - -/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */ -/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */ - -/* Define to 1 if you have the <direct.h> header file. */ -/* #undef HAVE_DIRECT_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <dmalloc.h> header file. */ -/* #undef HAVE_DMALLOC_H */ - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <openssl/aes.h> header file. */ -#define HAVE_OPENSSL_AES_H 1 - -/* Define to 1 if you have the <openssl/bn.h> header file. */ -#define HAVE_OPENSSL_BN_H 1 - -/* Define to 1 if you have the <openssl/camellia.h> header file. */ -#define HAVE_OPENSSL_CAMELLIA_H 1 -/*#ifndef OPENSSL_NO_CAMELLIA -#define OPENSSL_NO_CAMELLIA -#endif*/ - -/* Define to 1 if you have the <openssl/cast.h> header file. */ -#define HAVE_OPENSSL_CAST_H 1 - -/* Define to 1 if you have the <openssl/des.h> header file. */ -#define HAVE_OPENSSL_DES_H 1 - -/* Define to 1 if you have the <openssl/dsa.h> header file. */ -#define HAVE_OPENSSL_DSA_H 1 - -/* Define to 1 if you have the <openssl/err.h> header file. */ -#define HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the <openssl/idea.h> header file. */ -/* #undef HAVE_OPENSSL_IDEA_H */ -#ifndef OPENSSL_NO_IDEA -#define OPENSSL_NO_IDEA /* we would have IDEA on android, but we don't need it for netpgp; moreover, we want the same code on different systems */ -#endif - -/* Define to 1 if you have the <openssl/md5.h> header file. */ -#define HAVE_OPENSSL_MD5_H 1 - -/* Define to 1 if you have the <openssl/rand.h> header file. */ -#define HAVE_OPENSSL_RAND_H 1 - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the <openssl/sha.h> header file. */ -#define HAVE_OPENSSL_SHA_H 1 - -/* Define to 1 if the system has the type `SHA256_CTX'. */ -#define HAVE_SHA256_CTX 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the <sys/file.h> header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#define HAVE_SYS_MMAN_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the <zlib.h> header file. */ -#define HAVE_ZLIB_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "netpgp" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "Alistair Crooks <agc@netbsd.org> c0596823" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "netpgp" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "netpgp 20140220" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "netpgp" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "20140220" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "20140220" - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT64_T */ - -/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT8_T */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint16_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint64_t */ - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint8_t */ - - -#endif /* __CONFIG_NETPGP_H__ */ diff --git a/netpgp/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h b/netpgp/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h deleted file mode 100644 index 5163cff2cc359b35d61d9841f6a2c65f25a89507..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/config-original-as-configured-for-ubuntu-16.04-64bit.h +++ /dev/null @@ -1,187 +0,0 @@ -/* src/lib/config.h. Generated from config.h.in by configure. */ -/* src/lib/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the <bzlib.h> header file. */ -#define HAVE_BZLIB_H 1 - -/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */ -/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */ - -/* Define to 1 if you have the <direct.h> header file. */ -/* #undef HAVE_DIRECT_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <dmalloc.h> header file. */ -/* #undef HAVE_DMALLOC_H */ - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <openssl/aes.h> header file. */ -#define HAVE_OPENSSL_AES_H 1 - -/* Define to 1 if you have the <openssl/bn.h> header file. */ -#define HAVE_OPENSSL_BN_H 1 - -/* Define to 1 if you have the <openssl/camellia.h> header file. */ -#define HAVE_OPENSSL_CAMELLIA_H 1 - -/* Define to 1 if you have the <openssl/cast.h> header file. */ -#define HAVE_OPENSSL_CAST_H 1 - -/* Define to 1 if you have the <openssl/des.h> header file. */ -#define HAVE_OPENSSL_DES_H 1 - -/* Define to 1 if you have the <openssl/dsa.h> header file. */ -#define HAVE_OPENSSL_DSA_H 1 - -/* Define to 1 if you have the <openssl/err.h> header file. */ -#define HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the <openssl/idea.h> header file. */ -/* #undef HAVE_OPENSSL_IDEA_H */ - -/* Define to 1 if you have the <openssl/md5.h> header file. */ -#define HAVE_OPENSSL_MD5_H 1 - -/* Define to 1 if you have the <openssl/rand.h> header file. */ -#define HAVE_OPENSSL_RAND_H 1 - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the <openssl/sha.h> header file. */ -#define HAVE_OPENSSL_SHA_H 1 - -/* Define to 1 if the system has the type `SHA256_CTX'. */ -#define HAVE_SHA256_CTX 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the <sys/file.h> header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#define HAVE_SYS_MMAN_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the <zlib.h> header file. */ -#define HAVE_ZLIB_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "netpgp" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "Alistair Crooks <agc@netbsd.org> c0596823" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "netpgp" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "netpgp 20140220" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "netpgp" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "20140220" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "20140220" - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT64_T */ - -/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, - <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT8_T */ - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint16_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint64_t */ - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint8_t */ diff --git a/netpgp/netpgp/config-pep.h b/netpgp/netpgp/config-pep.h deleted file mode 100644 index 46097add4fc87469484f7f1c6e7a9f855d465a14..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/config-pep.h +++ /dev/null @@ -1,160 +0,0 @@ -// -// config.h -// netpgp - -#ifndef netpgp_config_h -#define netpgp_config_h - -/* Define to 1 if you have the <bzlib.h> header file. */ -#define HAVE_BZLIB_H 1 - -/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */ -#define HAVE_COMMONCRYPTO_COMMONDIGEST_H 1 - -/* Define to 1 if you have the <direct.h> header file. */ -/* #undef HAVE_DIRECT_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <dmalloc.h> header file. */ -/* #undef HAVE_DMALLOC_H */ - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if the system has the type 'long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the <malloc.h> header file. */ -/* #undef HAVE_MALLOC_H */ - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <openssl/aes.h> header file. */ -#define HAVE_OPENSSL_AES_H 1 - -/* Define to 1 if you have the <openssl/bn.h> header file. */ -#define HAVE_OPENSSL_BN_H 1 - -/* Define to 1 if you have the <openssl/camellia.h> header file. */ -/* #undef HAVE_OPENSSL_CAMELLIA_H */ - -/* Define to 1 if you have the <openssl/cast.h> header file. */ -#define HAVE_OPENSSL_CAST_H 1 - -/* Define to 1 if you have the <openssl/des.h> header file. */ -#define HAVE_OPENSSL_DES_H 1 - -/* Define to 1 if you have the <openssl/dsa.h> header file. */ -#define HAVE_OPENSSL_DSA_H 1 - -/* Define to 1 if you have the <openssl/err.h> header file. */ -#define HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the <openssl/idea.h> header file. */ -/* #undef HAVE_OPENSSL_IDEA_H */ - -/* Define to 1 if you have the <openssl/md5.h> header file. */ -#define HAVE_OPENSSL_MD5_H 1 - -/* Define to 1 if you have the <openssl/rand.h> header file. */ -#define HAVE_OPENSSL_RAND_H 1 - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the <openssl/sha.h> header file. */ -#define HAVE_OPENSSL_SHA_H 1 - -/* Define to 1 if the system has the type `SHA256_CTX'. */ -#define HAVE_SHA256_CTX 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/cdefs.h> header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the <sys/file.h> header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#define HAVE_SYS_MMAN_H 1 - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the <sys/resource.h> header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if the system has the type 'unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the <zlib.h> header file. */ -#define HAVE_ZLIB_H 1 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "netpgp" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "libetpan-devel@lists.sourceforge.net" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "netpgp" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "netpgp beta0" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "netpgp" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "beta0" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "beta0" - -#define OPENSSL_NO_IDEA 1 - -#endif diff --git a/netpgp/netpgp/create.h b/netpgp/netpgp/create.h deleted file mode 100644 index b7782d7ecaf2285cee31b31ec0e7f6424d36dcbe..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/create.h +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** \file - */ -#ifndef CREATE_H_ -#define CREATE_H_ - -#include "types.h" -#include "packet.h" -#include "crypto.h" -#include "errors.h" -#include "keyring.h" -#include "writer.h" -#include "memory.h" - -/** - * \ingroup Create - * This struct contains the required information about how to write this stream - */ -struct pgp_output_t { - pgp_writer_t writer; - pgp_error_t *errors; /* error stack */ -}; - -pgp_output_t *pgp_output_new(void); -void pgp_output_delete(pgp_output_t *); - -int pgp_filewrite(const char *, const char *, const size_t, const unsigned); - -void pgp_build_pubkey(pgp_memory_t *, const pgp_pubkey_t *, unsigned); - -unsigned pgp_calc_sesskey_checksum(pgp_pk_sesskey_t *, uint8_t *); -unsigned pgp_write_struct_userid(pgp_output_t *, const uint8_t *); -unsigned pgp_write_ss_header(pgp_output_t *, size_t, pgp_content_enum); -unsigned pgp_write_struct_seckey_ptag(const pgp_seckey_t *key, - const uint8_t *passphrase, - const size_t pplen, - pgp_output_t *output, - pgp_content_enum ptag); -unsigned pgp_write_struct_seckey(const pgp_seckey_t *, - const uint8_t *, - const size_t, - pgp_output_t *); -unsigned pgp_write_struct_pubkey(pgp_output_t *, const pgp_pubkey_t *); -unsigned pgp_write_one_pass_sig(pgp_output_t *, - const pgp_seckey_t *, - const pgp_hash_alg_t, - const pgp_sig_type_t); -unsigned pgp_write_litdata(pgp_output_t *, - const uint8_t *, - const int, - const pgp_litdata_enum); -pgp_pk_sesskey_t *pgp_create_pk_sesskey(pgp_key_t *, const char *, pgp_pk_sesskey_t *); -unsigned pgp_write_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *); -unsigned pgp_write_xfer_key(pgp_output_t *output, - const pgp_key_t *key, - const unsigned armoured); - -void pgp_fast_create_userid(uint8_t **, uint8_t *); -unsigned pgp_write_userid(const uint8_t *, pgp_output_t *); -void pgp_fast_create_rsa_pubkey(pgp_pubkey_t *, time_t, BIGNUM *, BIGNUM *); -unsigned pgp_write_rsa_pubkey(time_t, const BIGNUM *, const BIGNUM *, - pgp_output_t *); -void pgp_fast_create_rsa_seckey(pgp_seckey_t *, time_t, BIGNUM *, - BIGNUM *, BIGNUM *, BIGNUM *, - BIGNUM *, BIGNUM *); -unsigned encode_m_buf(const uint8_t *, size_t, const pgp_pubkey_t *, - uint8_t *); -unsigned pgp_fileread_litdata(const char *, const pgp_litdata_enum, - pgp_output_t *); -unsigned pgp_write_symm_enc_data(const uint8_t *, const int, - pgp_output_t *); - -#endif /* CREATE_H_ */ diff --git a/netpgp/netpgp/crypto.h b/netpgp/netpgp/crypto.h deleted file mode 100644 index bf80412cbc2515ece8a337cabd290b1d7d364cb7..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/crypto.h +++ /dev/null @@ -1,348 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef CRYPTO_H_ -#define CRYPTO_H_ - -#include "keyring.h" -#include "packet.h" -#include "memory.h" -#include "packet-parse.h" - -#include <openssl/dsa.h> - -#define PGP_MIN_HASH_SIZE 16 - -/** pgp_hash_t */ -struct pgp_hash_t { - pgp_hash_alg_t alg; /* algorithm */ - size_t size; /* size */ - const char *name; /* what it's known as */ - int (*init)(pgp_hash_t *); - void (*add)(pgp_hash_t *, const uint8_t *, unsigned); - unsigned (*finish)(pgp_hash_t *, uint8_t *); - void *data; /* blob for data */ -}; - -/** pgp_crypt_t */ -struct pgp_crypt_t { - pgp_symm_alg_t alg; - size_t blocksize; - size_t keysize; - void (*set_iv)(pgp_crypt_t *, const uint8_t *); - void (*set_crypt_key)(pgp_crypt_t *, const uint8_t *); - int (*base_init)(pgp_crypt_t *); - void (*decrypt_resync)(pgp_crypt_t *); - /* encrypt/decrypt one block */ - void (*block_encrypt)(pgp_crypt_t *, void *, const void *); - void (*block_decrypt)(pgp_crypt_t *, void *, const void *); - /* Standard CFB encrypt/decrypt (as used by Sym Enc Int Prot packets) */ - void (*cfb_encrypt)(pgp_crypt_t *, void *, const void *, size_t); - void (*cfb_decrypt)(pgp_crypt_t *, void *, const void *, size_t); - void (*decrypt_finish)(pgp_crypt_t *); - uint8_t iv[PGP_MAX_BLOCK_SIZE]; - uint8_t civ[PGP_MAX_BLOCK_SIZE]; - uint8_t siv[PGP_MAX_BLOCK_SIZE]; - /* siv is needed for weird v3 resync */ - uint8_t key[PGP_MAX_KEY_SIZE]; - int num; - /* num is offset - see openssl _encrypt doco */ - void *encrypt_key; - void *decrypt_key; -}; - -typedef struct pgp_validation_t { - unsigned validc; - pgp_sig_info_t *valid_sigs; - unsigned invalidc; - pgp_sig_info_t *invalid_sigs; - unsigned unknownc; - pgp_sig_info_t *unknown_sigs; - time_t birthtime; - time_t duration; -} pgp_validation_t; - -void pgp_crypto_finish(void); -void pgp_hash_md5(pgp_hash_t *); -void pgp_hash_sha1(pgp_hash_t *); -void pgp_hash_sha256(pgp_hash_t *); -void pgp_hash_sha512(pgp_hash_t *); -void pgp_hash_sha384(pgp_hash_t *); -void pgp_hash_sha224(pgp_hash_t *); -unsigned pgp_hash_any(pgp_hash_t *, pgp_hash_alg_t); -pgp_hash_alg_t pgp_str_to_hash_alg(const char *); -const char *pgp_text_from_hash(pgp_hash_t *); -unsigned pgp_hash_size(pgp_hash_alg_t); -unsigned pgp_hash(uint8_t *, pgp_hash_alg_t, const void *, size_t); - -void pgp_hash_add_int(pgp_hash_t *, unsigned, unsigned); - -unsigned pgp_dsa_verify(const uint8_t *, size_t, - const pgp_dsa_sig_t *, - const pgp_dsa_pubkey_t *); - -int pgp_rsa_public_decrypt(uint8_t *, const uint8_t *, size_t, - const pgp_rsa_pubkey_t *); -int pgp_rsa_public_encrypt(uint8_t *, const uint8_t *, size_t, - const pgp_rsa_pubkey_t *); - -int pgp_rsa_private_encrypt(uint8_t *, const uint8_t *, size_t, - const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *); -int pgp_rsa_private_decrypt(uint8_t *, const uint8_t *, size_t, - const pgp_rsa_seckey_t *, const pgp_rsa_pubkey_t *); - -int pgp_elgamal_public_encrypt(uint8_t *, uint8_t *, const uint8_t *, size_t, - const pgp_elgamal_pubkey_t *); -int pgp_elgamal_private_decrypt(uint8_t *, const uint8_t *, const uint8_t *, size_t, - const pgp_elgamal_seckey_t *, const pgp_elgamal_pubkey_t *); - -pgp_symm_alg_t pgp_str_to_cipher(const char *); -unsigned pgp_block_size(pgp_symm_alg_t); -unsigned pgp_key_size(pgp_symm_alg_t); - -int pgp_decrypt_data(pgp_content_enum, pgp_region_t *, - pgp_stream_t *); - -int pgp_crypt_any(pgp_crypt_t *, pgp_symm_alg_t); -void pgp_decrypt_init(pgp_crypt_t *); -void pgp_encrypt_init(pgp_crypt_t *); -size_t pgp_decrypt_se(pgp_crypt_t *, void *, const void *, size_t); -size_t pgp_encrypt_se(pgp_crypt_t *, void *, const void *, size_t); -size_t pgp_decrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t); -size_t pgp_encrypt_se_ip(pgp_crypt_t *, void *, const void *, size_t); -unsigned pgp_is_sa_supported(pgp_symm_alg_t); - -void pgp_reader_push_decrypt(pgp_stream_t *, pgp_crypt_t *, - pgp_region_t *); -void pgp_reader_pop_decrypt(pgp_stream_t *); - -/* Hash everything that's read */ -void pgp_reader_push_hash(pgp_stream_t *, pgp_hash_t *); -void pgp_reader_pop_hash(pgp_stream_t *); - -int pgp_decrypt_decode_mpi(uint8_t *, unsigned, const BIGNUM *, - const BIGNUM *, const pgp_seckey_t *); - -unsigned pgp_rsa_encrypt_mpi(const uint8_t *, const size_t, - const pgp_pubkey_t *, - pgp_pk_sesskey_params_t *); -unsigned pgp_elgamal_encrypt_mpi(const uint8_t *, const size_t, - const pgp_pubkey_t *, - pgp_pk_sesskey_params_t *); - -/* Encrypt everything that's written */ -struct pgp_key_data; -void pgp_writer_push_encrypt(pgp_output_t *, - const struct pgp_key_data *); - -unsigned pgp_encrypt_file(pgp_io_t *, const char *, const char *, - const pgp_key_t *, - const unsigned, const unsigned, const char *); -unsigned pgp_decrypt_file(pgp_io_t *, - const char *, - const char *, - pgp_keyring_t *, - pgp_keyring_t *, - const unsigned, - const unsigned, - const unsigned, - void *, - int, - pgp_cbfunc_t *); - -pgp_memory_t * -pgp_encrypt_buf(pgp_io_t *, const void *, const size_t, - const pgp_keyring_t *, - const unsigned, const char *, unsigned); -pgp_memory_t * -pgp_decrypt_buf(pgp_io_t *, - const void *, - const size_t, - pgp_keyring_t *, - pgp_keyring_t *, - const unsigned, - const unsigned, - void *, - int, - pgp_cbfunc_t *); - -pgp_memory_t * -pgp_decrypt_and_validate_buf(pgp_io_t *io, - pgp_validation_t *result, - const void *input, - const size_t insize, - pgp_keyring_t *secring, - pgp_keyring_t *pubring, - const unsigned use_armour, - key_id_t **recipients_key_ids, - unsigned *recipients_count); - -/* Keys */ -#if 0 ////// -pgp_key_t *pgp_rsa_new_selfsign_key(const int, - const unsigned long, const uint8_t *, const char *, - const char *); -#endif ////// - -unsigned pgp_rsa_generate_keypair(pgp_key_t *, - const int, - const unsigned long, - const char *, - const char *, - const uint8_t *, - const size_t); - -int pgp_dsa_size(const pgp_dsa_pubkey_t *); -pgp_dsa_sig_t *pgp_dsa_sign(uint8_t *, unsigned, - const pgp_dsa_seckey_t *, - const pgp_dsa_pubkey_t *); - -/** pgp_reader_t */ -struct pgp_reader_t { - pgp_reader_func_t *reader; /* reader func to get parse data */ - pgp_reader_destroyer_t *destroyer; - void *arg; /* args to pass to reader function */ - unsigned accumulate:1; /* set to gather packet data */ - uint8_t *accumulated; /* the accumulated data */ - unsigned asize; /* size of the buffer */ - unsigned alength;/* used buffer */ - unsigned position; /* reader-specific offset */ - pgp_reader_t *next; - pgp_stream_t *parent;/* parent parse_info structure */ - - unsigned partial_read:1; - unsigned coalescing:1; - /* used for partial length coalescing */ - unsigned virtualc; - unsigned virtualoff; - uint8_t *virtualpkt; -}; - - -/** pgp_cryptinfo_t - Encrypt/decrypt settings -*/ -struct pgp_cryptinfo_t { - char *passphrase; - pgp_keyring_t *secring; - pgp_key_t *keydata; - pgp_cbfunc_t *getpassphrase; - pgp_keyring_t *pubring; - DYNARRAY(key_id_t, recipients_key_ids); -}; - -/** pgp_cbdata_t */ -struct pgp_cbdata_t { - pgp_cbfunc_t *cbfunc; /* callback function */ - void *arg; /* args to pass to callback func */ - pgp_error_t **errors; /* address of error stack */ - pgp_cbdata_t *next; - pgp_output_t *output; /* when writing out parsed info */ - pgp_io_t *io; /* error/output messages */ - void *passfp; /* fp for passphrase input */ - pgp_cryptinfo_t cryptinfo; /* used when decrypting */ - pgp_printstate_t printstate; /* used to keep printing state */ - pgp_seckey_t *sshseckey; /* secret key for ssh */ - int numtries; /* # of passphrase attempts */ - int gotpass; /* when passphrase entered */ -}; - -/** pgp_hashtype_t */ -typedef struct { - pgp_hash_t hash; /* hashes we should hash data with */ - uint8_t keyid[PGP_KEY_ID_SIZE]; -} pgp_hashtype_t; - -#define NTAGS 0x100 /* == 256 */ - -/** \brief Structure to hold information about a packet parse. - * - * This information includes options about the parse: - * - whether the packet contents should be accumulated or not - * - whether signature subpackets should be parsed or left raw - * - * It contains options specific to the parsing of armoured data: - * - whether headers are allowed in armoured data without a gap - * - whether a blank line is allowed at the start of the armoured data - * - * It also specifies : - * - the callback function to use and its arguments - * - the reader function to use and its arguments - * - * It also contains information about the current state of the parse: - * - offset from the beginning - * - the accumulated data, if any - * - the size of the buffer, and how much has been used - * - * It has a linked list of errors. - */ - -struct pgp_stream_t { - uint8_t ss_raw[NTAGS / 8]; - /* 1 bit / sig-subpkt type; set to get raw data */ - uint8_t ss_parsed[NTAGS / 8]; - /* 1 bit / sig-subpkt type; set to get parsed data */ - pgp_reader_t readinfo; - pgp_cbdata_t cbinfo; - pgp_error_t *errors; - void *io; /* io streams */ - pgp_crypt_t decrypt; - pgp_cryptinfo_t cryptinfo; - size_t hashc; - pgp_hashtype_t *hashes; - //unsigned reading_v3_secret:1; - //unsigned reading_mpi_len:1; - //unsigned exact_read:1; - -}; - -#endif /* CRYPTO_H_ */ diff --git a/netpgp/netpgp/defs.h b/netpgp/netpgp/defs.h deleted file mode 100644 index 760f1d309a4c2ed774f398ce9046086c1fe1bb1f..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/defs.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD$ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef DEFS_H_ -#define DEFS_H_ - -#include <sys/types.h> -#include <sys/param.h> - -#ifdef HAVE_INTTYPES_H -#include <inttypes.h> -#endif - -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define NEWARRAY(type,ptr,size,where,action) do { \ - if ((ptr = calloc(sizeof(type), (unsigned)(size))) == NULL) { \ - (void) fprintf(stderr, "%s: can't allocate %lu bytes\n", \ - where, (unsigned long)(size * sizeof(type))); \ - action; \ - } \ -} while( /* CONSTCOND */ 0) - -#define RENEW(type,ptr,size,where,action) do { \ - type *_newptr; \ - _newptr = realloc(ptr, (size_t)(sizeof(type) * (size))); \ - if (_newptr == NULL) { \ - (void) fprintf(stderr, "%s: can't realloc %lu bytes\n", \ - where, (unsigned long)(size * sizeof(type))); \ - action; \ - } else { \ - ptr = _newptr; \ - } \ -} while( /* CONSTCOND */ 0) - -#define NEW(type, ptr, where, action) NEWARRAY(type, ptr, 1, where, action) - -#define FREE(ptr) (void) free(ptr) - -#define ALLOC(type, v, size, c, init, incr, where, action) do { \ - uint32_t _newsize = size; \ - if (size == 0) { \ - _newsize = init; \ - NEWARRAY(type, v, _newsize, where ": new", action); \ - } else if (c == size) { \ - _newsize = size + incr; \ - RENEW(type, v, _newsize, where ": renew", action); \ - } \ - size = _newsize; \ -} while( /* CONSTCOND */ 0) - -#define DEFINE_ARRAY(name, type) \ -typedef struct name { \ - uint32_t c; \ - uint32_t size; \ - type *v; \ -} name - -#endif /* !DEFS_H_ */ diff --git a/netpgp/netpgp/errors.h b/netpgp/netpgp/errors.h deleted file mode 100644 index ab518d08c67c61cc3dae8cbd44e6318a5a968ad0..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/errors.h +++ /dev/null @@ -1,170 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef ERRORS_H_ -#define ERRORS_H_ - -#include <errno.h> - -#ifndef __printflike -#define __printflike(n, m) __attribute__((format(printf,n,m))) -#endif - -/** error codes */ -/* Remember to add names to map in errors.c */ -typedef enum { - PGP_E_OK = 0x0000, /* no error */ - PGP_E_FAIL = 0x0001, /* general error */ - PGP_E_SYSTEM_ERROR = 0x0002, /* system error, look at errno for - * details */ - PGP_E_UNIMPLEMENTED = 0x0003, /* feature not yet implemented */ - - /* reader errors */ - PGP_E_R = 0x1000, /* general reader error */ - PGP_E_R_READ_FAILED = PGP_E_R + 1, - PGP_E_R_EARLY_EOF = PGP_E_R + 2, - PGP_E_R_BAD_FORMAT = PGP_E_R + 3, /* For example, malformed - * armour */ - PGP_E_R_UNSUPPORTED = PGP_E_R + 4, - PGP_E_R_UNCONSUMED_DATA = PGP_E_R + 5, - - /* writer errors */ - PGP_E_W = 0x2000, /* general writer error */ - PGP_E_W_WRITE_FAILED = PGP_E_W + 1, - PGP_E_W_WRITE_TOO_SHORT = PGP_E_W + 2, - - /* parser errors */ - PGP_E_P = 0x3000, /* general parser error */ - PGP_E_P_NOT_ENOUGH_DATA = PGP_E_P + 1, - PGP_E_P_UNKNOWN_TAG = PGP_E_P + 2, - PGP_E_P_PACKET_CONSUMED = PGP_E_P + 3, - PGP_E_P_MPI_FORMAT_ERROR = PGP_E_P + 4, - PGP_E_P_PACKET_NOT_CONSUMED = PGP_E_P + 5, - PGP_E_P_DECOMPRESSION_ERROR = PGP_E_P + 6, - PGP_E_P_NO_USERID = PGP_E_P + 7, - - /* creator errors */ - PGP_E_C = 0x4000, /* general creator error */ - - /* validation errors */ - PGP_E_V = 0x5000, /* general validation error */ - PGP_E_V_BAD_SIGNATURE = PGP_E_V + 1, - PGP_E_V_NO_SIGNATURE = PGP_E_V + 2, - PGP_E_V_UNKNOWN_SIGNER = PGP_E_V + 3, - PGP_E_V_BAD_HASH = PGP_E_V + 4, - - /* Algorithm support errors */ - PGP_E_ALG = 0x6000, /* general algorithm error */ - PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG = PGP_E_ALG + 1, - PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG = PGP_E_ALG + 2, - PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG = PGP_E_ALG + 3, - PGP_E_ALG_UNSUPPORTED_HASH_ALG = PGP_E_ALG + 4, - PGP_E_ALG_UNSUPPORTED_COMPRESS_ALG = PGP_E_ALG + 5, - - /* Protocol errors */ - PGP_E_PROTO = 0x7000, /* general protocol error */ - PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT = PGP_E_PROTO + 2, - PGP_E_PROTO_UNKNOWN_SS = PGP_E_PROTO + 3, - PGP_E_PROTO_CRITICAL_SS_IGNORED = PGP_E_PROTO + 4, - PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN = PGP_E_PROTO + 5, - PGP_E_PROTO_BAD_SIGNATURE_VRSN = PGP_E_PROTO + 6, - PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN = PGP_E_PROTO + 7, - PGP_E_PROTO_BAD_PKSK_VRSN = PGP_E_PROTO + 8, - PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN = PGP_E_PROTO + 9, - PGP_E_PROTO_BAD_SK_CHECKSUM = PGP_E_PROTO + 10 -} pgp_errcode_t; - -/** one entry in a linked list of errors */ -typedef struct pgp_error { - pgp_errcode_t errcode; - int sys_errno; /* irrelevent unless errcode == - * PGP_E_SYSTEM_ERROR */ - char *comment; - const char *file; - int line; - struct pgp_error *next; -} pgp_error_t; - -const char *pgp_errcode(const pgp_errcode_t); - -void -pgp_push_error(pgp_error_t **, pgp_errcode_t, - int, - const char *, int, const char *,...) __printflike(6, 7); -void pgp_print_error(pgp_error_t *); -void pgp_print_errors(pgp_error_t *); -void pgp_free_errors(pgp_error_t *); -int pgp_has_error(pgp_error_t *, pgp_errcode_t); - -#define PGP_SYSTEM_ERROR_1(err,code,sys,fmt,arg) do { \ - pgp_push_error(err,PGP_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,sys);\ - pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \ -} while(/*CONSTCOND*/0) - -#define PGP_MEMORY_ERROR(err) { \ - fprintf(stderr, "Memory error\n"); \ -} /* \todo placeholder for better error - * handling */ -#define PGP_ERROR_1(err,code,fmt,arg) do { \ - pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \ -} while(/*CONSTCOND*/0) -#define PGP_ERROR_2(err,code,fmt,arg,arg2) do { \ - pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2); \ -} while(/*CONSTCOND*/0) -#define PGP_ERROR_3(err,code,fmt,arg,arg2,arg3) do { \ - pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3); \ -} while(/*CONSTCOND*/0) -#define PGP_ERROR_4(err,code,fmt,arg,arg2,arg3,arg4) do { \ - pgp_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3,arg4); \ -} while(/*CONSTCOND*/0) - -#endif /* ERRORS_H_ */ diff --git a/netpgp/netpgp/keyring.h b/netpgp/netpgp/keyring.h deleted file mode 100644 index db6291b90177096d8b9a1ab03d67697c3c440b02..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/keyring.h +++ /dev/null @@ -1,206 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef KEYRING_H_ -#define KEYRING_H_ - -#include "packet.h" -#include "packet-parse.h" -#include "memory.h" - -enum { - MAX_ID_LENGTH = 128, - MAX_PASSPHRASE_LENGTH = 256 -}; - -typedef struct pgp_key_t pgp_key_t; - -/** \struct pgp_keyring_t - * A keyring - */ -typedef struct pgp_keyring_t { - DYNARRAY(pgp_key_t, key); - pgp_hash_alg_t hashtype; -} pgp_keyring_t; - -pgp_key_t *pgp_getkeybyid(pgp_io_t *, - const pgp_keyring_t *, - const uint8_t *, - unsigned *, - pgp_pubkey_t **, - pgp_seckey_t **, - unsigned checkrevoke, - unsigned checkexpiry); -unsigned pgp_deletekeybyid(pgp_io_t *, - pgp_keyring_t *, - const uint8_t *); -pgp_key_t *pgp_getkeybyfpr(pgp_io_t *, - const pgp_keyring_t *, - const uint8_t *fpr, - size_t length, - unsigned *from, - pgp_pubkey_t **, - unsigned checkrevoke, - unsigned checkexpiry); -unsigned pgp_deletekeybyfpr(pgp_io_t *, - pgp_keyring_t *, - const uint8_t *fpr, - size_t length); -const pgp_key_t *pgp_getkeybyname(pgp_io_t *, - const pgp_keyring_t *, - const char *); -const pgp_key_t *pgp_getnextkeybyname(pgp_io_t *, - const pgp_keyring_t *, - const char *, - unsigned *); -void pgp_key_free(pgp_key_t *); -void pgp_keydata_free(pgp_key_t *); -void pgp_keyring_free(pgp_keyring_t *); -void pgp_keyring_purge(pgp_keyring_t *); -void pgp_dump_keyring(const pgp_keyring_t *); -pgp_pubkey_t *pgp_key_get_pubkey(pgp_key_t *); -unsigned pgp_is_key_secret(pgp_key_t *); -pgp_seckey_t *pgp_get_seckey(pgp_key_t *); -pgp_seckey_t *pgp_get_writable_seckey(pgp_key_t *); -// pgp_seckey_t *pgp_decrypt_seckey(const pgp_key_t *, void *); - -unsigned -pgp_keyring_fileread(pgp_io_t *io, - pgp_keyring_t *pubring, - pgp_keyring_t *secring, - const unsigned armour, - const char *filename); - -unsigned -pgp_keyring_read_from_mem(pgp_io_t *io, - pgp_keyring_t *pubring, - pgp_keyring_t *secring, - const unsigned armour, - pgp_memory_t *mem); - -int pgp_keyring_list(pgp_io_t *, const pgp_keyring_t *, const int); - -void pgp_forget(void *, unsigned); - -// uint8_t *pgp_add_userid(pgp_key_t *, const uint8_t *); -unsigned pgp_update_userid( - pgp_key_t *key, - const uint8_t *userid, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo); - -// pgp_subpacket_t *pgp_add_subpacket(pgp_key_t *, -// const pgp_subpacket_t *); -// pgp_subpacket_t *pgp_replace_subpacket(pgp_key_t *, -// const pgp_subpacket_t *, -// unsigned ); - -unsigned pgp_add_selfsigned_userid(pgp_key_t *skey, pgp_key_t *pkey, const uint8_t *userid, time_t duration); - -pgp_key_t *pgp_keydata_new(void); -void pgp_keydata_init(pgp_key_t *, const pgp_content_enum); - -char *pgp_export_key(pgp_io_t *, const pgp_key_t *, uint8_t *); - -int pgp_keyring_add(pgp_keyring_t *, const pgp_key_t *); -// int pgp_add_to_pubring(pgp_keyring_t *, const pgp_pubkey_t *, pgp_content_enum tag); -pgp_key_t *pgp_ensure_pubkey( - pgp_keyring_t *, - pgp_pubkey_t *, - uint8_t *); -pgp_key_t *pgp_ensure_seckey( - pgp_keyring_t *keyring, - pgp_seckey_t *seckey, - uint8_t *pubkeyid); -unsigned pgp_add_directsig( - pgp_key_t *key, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo); -unsigned pgp_update_subkey( - pgp_key_t *key, - pgp_content_enum subkeytype, - pgp_keydata_key_t *subkey, - const pgp_subpacket_t *sigpkt, - pgp_sig_info_t *siginfo); -// int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *); - -int pgp_append_keyring(pgp_keyring_t *, pgp_keyring_t *); - -pgp_subpacket_t * pgp_copy_packet(pgp_subpacket_t *, const pgp_subpacket_t *); -uint8_t * pgp_copy_userid(uint8_t **dst, const uint8_t *src); - -const int32_t pgp_key_get_uid0(pgp_key_t *keydata); -const uint8_t *pgp_key_get_primary_userid(pgp_key_t *key); - - -pgp_pubkey_t * pgp_key_get_sigkey(pgp_key_t *key); -pgp_seckey_t * pgp_key_get_certkey(pgp_key_t *key); -pgp_pubkey_t * pgp_key_get_enckey(pgp_key_t *key, const uint8_t **id); -pgp_seckey_t * pgp_key_get_deckey(pgp_key_t *key, const uint8_t **id); - -const int32_t -pgp_key_find_uid_cond( - const pgp_key_t *key, - unsigned(*uidcond) ( uint8_t *, void *), - void *uidcondarg, - unsigned(*sigcond) ( const pgp_sig_info_t *, void *), - void *sigcondarg, - time_t *youngest, - unsigned checkrevoke, - unsigned checkexpiry); - -const pgp_key_rating_t pgp_key_get_rating(pgp_key_t *key); - -unsigned -pgp_key_revoke(pgp_key_t *skey, pgp_key_t *pkey, uint8_t code, const char *reason); - -#endif /* KEYRING_H_ */ diff --git a/netpgp/netpgp/memory.h b/netpgp/netpgp/memory.h deleted file mode 100644 index d8bd576340ad4199508ce6307706e9b033284aa5..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/memory.h +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#ifndef MEMORY_H_ -#define MEMORY_H_ - -#include <sys/types.h> - -#include "packet.h" - -/** pgp_memory_t - */ -typedef struct pgp_memory_t { - uint8_t *buf; - size_t length; - size_t allocated; - unsigned mmapped; -} pgp_memory_t; - - -pgp_memory_t *pgp_memory_new(void); -void pgp_memory_free(pgp_memory_t *); -void pgp_memory_init(pgp_memory_t *, size_t); -void pgp_memory_pad(pgp_memory_t *, size_t); -void pgp_memory_add(pgp_memory_t *, const uint8_t *, size_t); -void pgp_memory_place_int(pgp_memory_t *, unsigned, unsigned, size_t); -void pgp_memory_make_packet(pgp_memory_t *, pgp_content_enum); -void pgp_memory_clear(pgp_memory_t *); -void pgp_memory_release(pgp_memory_t *); - -void pgp_writer_set_memory(pgp_output_t *, pgp_memory_t *); - -size_t pgp_mem_len(const pgp_memory_t *); -void *pgp_mem_data(pgp_memory_t *); -int pgp_mem_readfile(pgp_memory_t *, const char *); - -void pgp_random(void *, size_t); - -#endif /* MEMORY_H_ */ diff --git a/netpgp/netpgp/netpgpdefs.h b/netpgp/netpgp/netpgpdefs.h deleted file mode 100644 index 087f981ee09573db4f5a9f57e56b033c03f707c3..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/netpgpdefs.h +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@netbsd.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NETPGPDEFS_H_ -#define NETPGPDEFS_H_ 1 - -#define PRItime "ll" - -#ifdef WIN32 -#define PRIsize "I" -#else -#define PRIsize "z" -#endif - -/* for silencing unused parameter warnings */ -#define __PGP_USED(x) /*LINTED*/(void)&(x) - -#ifndef __UNCONST -#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) -#endif - -/* number of elements in an array */ -#define PGP_ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) - -void hexdump(FILE *, const char *, const uint8_t *, size_t); - -const char *pgp_str_from_map(int, pgp_map_t *); - -int pgp_set_debug_level(const char *); -int pgp_get_debug_level(const char *); - -void *pgp_new(size_t); - -#define NETPGP_BUFSIZ 8192 - -#define CALLBACK(t, cbinfo, pkt) do { \ - (pkt)->tag = (t); \ - if (pgp_callback(pkt, cbinfo) == PGP_RELEASE_MEMORY) { \ - pgp_parser_content_free(pkt); \ - } \ -} while(/* CONSTCOND */0) - -#ifndef MIN -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) /*EDIT BY MR*/ -#endif - -#endif /* !NETPGPDEFS_H_ */ diff --git a/netpgp/netpgp/netpgpdigest.h b/netpgp/netpgp/netpgpdigest.h deleted file mode 100644 index be776c456d7f415ba0f27124fc383e7e12136a78..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/netpgpdigest.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@netbsd.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NETPGPDIGEST_H_ -#define NETPGPDIGEST_H_ - -/* header file to define the sizes for various digest arrays */ - -#ifdef HAVE_OPENSSL_MD5_H -#include <openssl/md5.h> -#endif - -#ifdef HAVE_OPENSSL_SHA_H -#include <openssl/sha.h> -#endif - -/* Apple */ -#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H -#undef MD5_DIGEST_LENGTH -#undef SHA_DIGEST_LENGTH -#define COMMON_DIGEST_FOR_OPENSSL 1 -#include <CommonCrypto/CommonDigest.h> -#endif - -/* SHA1 Hash Size */ -#define PGP_SHA1_HASH_SIZE SHA_DIGEST_LENGTH -#define PGP_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH -#define PGP_SHA512_HASH_SIZE SHA512_DIGEST_LENGTH -#define PGP_CHECKHASH_SIZE PGP_SHA1_HASH_SIZE - -#endif /* NETPGPDIGEST_H_ */ diff --git a/netpgp/netpgp/netpgpsdk.h b/netpgp/netpgp/netpgpsdk.h deleted file mode 100644 index 4747b26097ca5fccda47706e72acb8477c98e2a6..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/netpgpsdk.h +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2009,2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NETPGPSDK_H_ -#define NETPGPSDK_H_ - -#include "keyring.h" -#include "crypto.h" -#include "signature.h" -#include "packet-show.h" - -#ifndef __printflike -#define __printflike(n, m) __attribute__((format(printf,n,m))) -#endif - -void pgp_validate_result_free(pgp_validation_t *); - -unsigned -pgp_validate_all_sigs(pgp_validation_t *, - const pgp_keyring_t *, - pgp_cb_ret_t cb(const pgp_packet_t *, pgp_cbdata_t *)); - -unsigned pgp_check_sig(const uint8_t *, - unsigned, const pgp_sig_t *, const pgp_pubkey_t *); - -const char *pgp_get_info(const char *type); - -int pgp_asprintf(char **, const char *, ...) __printflike(2, 3); - -void netpgp_log(const char *, ...) __printflike(1, 2); - -int netpgp_strcasecmp(const char *, const char *); -char *netpgp_strdup(const char *); - -#endif diff --git a/netpgp/netpgp/openssl11stub.h b/netpgp/netpgp/openssl11stub.h deleted file mode 100644 index 5d759ff8808a7962ff2e352774b89822d51a9c2c..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/openssl11stub.h +++ /dev/null @@ -1,133 +0,0 @@ - -int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -{ - /* If the fields n and e in r are NULL, the corresponding input - * parameters MUST be non-NULL for n and e. d may be - * left NULL (in case only the public key is used). - */ - if ((r->n == NULL && n == NULL) - || (r->e == NULL && e == NULL)) - return 0; - - if (n != NULL) { - BN_free(r->n); - r->n = n; - } - if (e != NULL) { - BN_free(r->e); - r->e = e; - } - if (d != NULL) { - BN_free(r->d); - r->d = d; - } - - return 1; -} - -int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) -{ - /* If the fields p and q in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->p == NULL && p == NULL) - || (r->q == NULL && q == NULL)) - return 0; - - if (p != NULL) { - BN_free(r->p); - r->p = p; - } - if (q != NULL) { - BN_free(r->q); - r->q = q; - } - - return 1; -} - -void RSA_get0_key(const RSA *r, - const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) - *n = r->n; - if (e != NULL) - *e = r->e; - if (d != NULL) - *d = r->d; -} - -void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -{ - if (p != NULL) - *p = r->p; - if (q != NULL) - *q = r->q; -} - -int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} - -void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) - *pr = sig->r; - if (ps != NULL) - *ps = sig->s; -} - -int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) -{ - /* If the fields p, q and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((d->p == NULL && p == NULL) - || (d->q == NULL && q == NULL) - || (d->g == NULL && g == NULL)) - return 0; - - if (p != NULL) { - BN_free(d->p); - d->p = p; - } - if (q != NULL) { - BN_free(d->q); - d->q = q; - } - if (g != NULL) { - BN_free(d->g); - d->g = g; - } - - return 1; -} - -int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) -{ - /* If the field pub_key in d is NULL, the corresponding input - * parameters MUST be non-NULL. The priv_key field may - * be left NULL. - */ - if (d->pub_key == NULL && pub_key == NULL) - return 0; - - if (pub_key != NULL) { - BN_free(d->pub_key); - d->pub_key = pub_key; - } - if (priv_key != NULL) { - BN_free(d->priv_key); - d->priv_key = priv_key; - } - - return 1; -} - diff --git a/netpgp/netpgp/packet-parse.h b/netpgp/netpgp/packet-parse.h deleted file mode 100644 index 0406ff031453fc87d103334b74f49b3e0ced86a8..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/packet-parse.h +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * Parser for OpenPGP packets - headers. - */ - -#ifndef PACKET_PARSE_H_ -#define PACKET_PARSE_H_ - -#include "types.h" -#include "packet.h" - -/** pgp_region_t */ -typedef struct pgp_region_t { - struct pgp_region_t *parent; - unsigned length; - unsigned readc; /* length read */ - unsigned last_read; - /* length of last read, only valid in deepest child */ - unsigned indeterminate:1; -} pgp_region_t; - -void pgp_init_subregion(pgp_region_t *, pgp_region_t *); - -/** pgp_cb_ret_t */ -typedef enum { - PGP_RELEASE_MEMORY, - PGP_KEEP_MEMORY, - PGP_FINISHED -} pgp_cb_ret_t; - -typedef struct pgp_cbdata_t pgp_cbdata_t; - -typedef pgp_cb_ret_t pgp_cbfunc_t(const pgp_packet_t *, - pgp_cbdata_t *); - -pgp_cb_ret_t -get_passphrase_cb(const pgp_packet_t *, pgp_cbdata_t *); - -typedef struct pgp_stream_t pgp_stream_t; -typedef struct pgp_reader_t pgp_reader_t; -typedef struct pgp_cryptinfo_t pgp_cryptinfo_t; - -/* - A reader MUST read at least one byte if it can, and should read up - to the number asked for. Whether it reads more for efficiency is - its own decision, but if it is a stacked reader it should never - read more than the length of the region it operates in (which it - would have to be given when it is stacked). - - If a read is short because of EOF, then it should return the short - read (obviously this will be zero on the second attempt, if not the - first). Because a reader is not obliged to do a full read, only a - zero return can be taken as an indication of EOF. - - If there is an error, then the callback should be notified, the - error stacked, and -1 should be returned. - - Note that although length is a size_t, a reader will never be asked - to read more than INT_MAX in one go. - - */ -typedef int pgp_reader_func_t(pgp_stream_t *, void *, size_t, pgp_error_t **, - pgp_reader_t *, pgp_cbdata_t *); - -typedef void pgp_reader_destroyer_t(pgp_reader_t *); - -void pgp_stream_delete(pgp_stream_t *); -pgp_error_t *pgp_stream_get_errors(pgp_stream_t *); -pgp_crypt_t *pgp_get_decrypt(pgp_stream_t *); - -void pgp_set_callback(pgp_stream_t *, pgp_cbfunc_t *, void *); -void pgp_callback_push(pgp_stream_t *, pgp_cbfunc_t *, void *); -void *pgp_callback_arg(pgp_cbdata_t *); -void *pgp_callback_errors(pgp_cbdata_t *); -void pgp_reader_set(pgp_stream_t *, pgp_reader_func_t *, - pgp_reader_destroyer_t *, void *); -void pgp_reader_push(pgp_stream_t *, pgp_reader_func_t *, - pgp_reader_destroyer_t *, void *); -void pgp_reader_pop(pgp_stream_t *); - -void *pgp_reader_get_arg(pgp_reader_t *); - -pgp_cb_ret_t pgp_callback(const pgp_packet_t *, - pgp_cbdata_t *); -pgp_cb_ret_t pgp_stacked_callback(const pgp_packet_t *, - pgp_cbdata_t *); -pgp_reader_t *pgp_readinfo(pgp_stream_t *); - -int pgp_parse(pgp_stream_t *, const int); - -/** Used to specify whether subpackets should be returned raw, parsed -* or ignored. */ -typedef enum { - PGP_PARSE_RAW, /* Callback Raw */ - PGP_PARSE_PARSED, /* Callback Parsed */ - PGP_PARSE_IGNORE /* Don't callback */ -} pgp_parse_type_t; - -void pgp_parse_options(pgp_stream_t *, pgp_content_enum, - pgp_parse_type_t); - -unsigned pgp_limited_read(pgp_stream_t *, uint8_t *, size_t, pgp_region_t *, - pgp_error_t **, pgp_reader_t *, - pgp_cbdata_t *); -unsigned pgp_stacked_limited_read(pgp_stream_t *, uint8_t *, unsigned, - pgp_region_t *, pgp_error_t **, - pgp_reader_t *, pgp_cbdata_t *); -void pgp_parse_hash_init(pgp_stream_t *, pgp_hash_alg_t, - const uint8_t *); -void pgp_parse_hash_data(pgp_stream_t *, const void *, size_t); -void pgp_parse_hash_finish(pgp_stream_t *); -pgp_hash_t *pgp_parse_hash_find(pgp_stream_t *, const uint8_t *); - -pgp_reader_func_t pgp_stacked_read; - -int pgp_decompress(pgp_region_t *, pgp_stream_t *, - pgp_compression_type_t); -unsigned pgp_writez(pgp_output_t *, const uint8_t *, - const unsigned); - -void -copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src); - -#endif /* PACKET_PARSE_H_ */ diff --git a/netpgp/netpgp/packet-show.h b/netpgp/netpgp/packet-show.h deleted file mode 100644 index 021727075da5b68a047550d29e2bc068e19daa1c..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/packet-show.h +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef PACKET_SHOW_H_ -#define PACKET_SHOW_H_ - -#include "packet.h" - -/** pgp_list_t - */ -typedef struct { - unsigned size; /* num of array slots allocated */ - unsigned used; /* num of array slots currently used */ - char **strings; -} pgp_list_t; - -/** pgp_text_t - */ -typedef struct { - pgp_list_t known; - pgp_list_t unknown; -} pgp_text_t; - -/** pgp_bit_map_t - */ -typedef struct { - uint8_t mask; - const char *string; -} pgp_bit_map_t; - -void pgp_text_init(pgp_text_t *); -void pgp_text_free(pgp_text_t *); - -const char *pgp_show_packet_tag(pgp_content_enum); -const char *pgp_show_ss_type(pgp_content_enum); - -const char *pgp_show_sig_type(pgp_sig_type_t); -const char *pgp_show_pka(pgp_pubkey_alg_t); - -const char *pgp_show_ss_zpref(uint8_t); - -const char *pgp_show_hash_alg(uint8_t); -const char *pgp_show_symm_alg(uint8_t); - -pgp_text_t *pgp_showall_ss_skapref(const pgp_data_t *); -const char *pgp_show_ss_skapref(uint8_t); - -const char *pgp_show_ss_rr_code(pgp_ss_rr_code_t); - -pgp_text_t *pgp_showall_ss_features(pgp_data_t); - -const char *pgp_show_ss_key_flag(uint8_t, pgp_bit_map_t *); - -const char *pgp_show_keyserv_pref(uint8_t, pgp_bit_map_t *); - -pgp_text_t *pgp_showall_notation(pgp_ss_notation_t); - -#endif /* PACKET_SHOW_H_ */ diff --git a/netpgp/netpgp/packet.h b/netpgp/netpgp/packet.h deleted file mode 100644 index d8d0171921e53abf7d3ddec1f161857275280ffa..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/packet.h +++ /dev/null @@ -1,1017 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * packet related headers. - */ - -#ifndef PACKET_H_ -#define PACKET_H_ - -#include <time.h> - -#ifdef HAVE_OPENSSL_BN_H -#include <openssl/bn.h> -#endif - -#include <openssl/ossl_typ.h> - -#include "types.h" -#include "errors.h" - -/* structure to keep track of printing state variables */ -typedef struct pgp_printstate_t { - unsigned unarmoured; - unsigned skipping; - int indent; -} pgp_printstate_t; - -/** General-use structure for variable-length data - */ - -typedef struct { - size_t len; - uint8_t *contents; - uint8_t mmapped; /* contents need an munmap(2) */ -} pgp_data_t; - -/************************************/ -/* Packet Tags - RFC4880, 4.2 */ -/************************************/ - -/** Packet Tag - Bit 7 Mask (this bit is always set). - * The first byte of a packet is the "Packet Tag". It always - * has bit 7 set. This is the mask for it. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_ALWAYS_SET 0x80 - -/** Packet Tag - New Format Flag. - * Bit 6 of the Packet Tag is the packet format indicator. - * If it is set, the new format is used, if cleared the - * old format is used. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_NEW_FORMAT 0x40 - - -/** Old Packet Format: Mask for content tag. - * In the old packet format bits 5 to 2 (including) - * are the content tag. This is the mask to apply - * to the packet tag. Note that you need to - * shift by #PGP_PTAG_OF_CONTENT_TAG_SHIFT bits. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_OF_CONTENT_TAG_MASK 0x3c -/** Old Packet Format: Offset for the content tag. - * As described at #PGP_PTAG_OF_CONTENT_TAG_MASK the - * content tag needs to be shifted after being masked - * out from the Packet Tag. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_OF_CONTENT_TAG_SHIFT 2 -/** Old Packet Format: Mask for length type. - * Bits 1 and 0 of the packet tag are the length type - * in the old packet format. - * - * See #pgp_ptag_of_lt_t for the meaning of the values. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_OF_LENGTH_TYPE_MASK 0x03 - - -/** Old Packet Format Lengths. - * Defines the meanings of the 2 bits for length type in the - * old packet format. - * - * \see RFC4880 4.2.1 - */ -typedef enum { - PGP_PTAG_OLD_LEN_1 = 0x00, /* Packet has a 1 byte length - - * header is 2 bytes long. */ - PGP_PTAG_OLD_LEN_2 = 0x01, /* Packet has a 2 byte length - - * header is 3 bytes long. */ - PGP_PTAG_OLD_LEN_4 = 0x02, /* Packet has a 4 byte - * length - header is 5 bytes - * long. */ - PGP_PTAG_OLD_LEN_INDETERMINATE = 0x03 /* Packet has a - * indeterminate length. */ -} pgp_ptag_of_lt_t; - - -/** New Packet Format: Mask for content tag. - * In the new packet format the 6 rightmost bits - * are the content tag. This is the mask to apply - * to the packet tag. Note that you need to - * shift by #PGP_PTAG_NF_CONTENT_TAG_SHIFT bits. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_NF_CONTENT_TAG_MASK 0x3f -/** New Packet Format: Offset for the content tag. - * As described at #PGP_PTAG_NF_CONTENT_TAG_MASK the - * content tag needs to be shifted after being masked - * out from the Packet Tag. - * - * \see RFC4880 4.2 - */ -#define PGP_PTAG_NF_CONTENT_TAG_SHIFT 0 - -/* PTag Content Tags */ -/***************************/ - -/** Package Tags (aka Content Tags) and signature subpacket types. - * This enumerates all rfc-defined packet tag values and the - * signature subpacket type values that we understand. - * - * \see RFC4880 4.3 - * \see RFC4880 5.2.3.1 - */ -typedef enum { - PGP_PTAG_CT_RESERVED = 0, /* Reserved - a packet tag must - * not have this value */ - PGP_PTAG_CT_PK_SESSION_KEY = 1, /* Public-Key Encrypted Session - * Key Packet */ - PGP_PTAG_CT_SIGNATURE = 2, /* Signature Packet */ - PGP_PTAG_CT_SK_SESSION_KEY = 3, /* Symmetric-Key Encrypted Session - * Key Packet */ - PGP_PTAG_CT_1_PASS_SIG = 4, /* One-Pass Signature - * Packet */ - PGP_PTAG_CT_SECRET_KEY = 5, /* Secret Key Packet */ - PGP_PTAG_CT_PUBLIC_KEY = 6, /* Public Key Packet */ - PGP_PTAG_CT_SECRET_SUBKEY = 7, /* Secret Subkey Packet */ - PGP_PTAG_CT_COMPRESSED = 8, /* Compressed Data Packet */ - PGP_PTAG_CT_SE_DATA = 9,/* Symmetrically Encrypted Data Packet */ - PGP_PTAG_CT_MARKER = 10,/* Marker Packet */ - PGP_PTAG_CT_LITDATA = 11, /* Literal Data Packet */ - PGP_PTAG_CT_TRUST = 12, /* Trust Packet */ - PGP_PTAG_CT_USER_ID = 13, /* User ID Packet */ - PGP_PTAG_CT_PUBLIC_SUBKEY = 14, /* Public Subkey Packet */ - PGP_PTAG_CT_RESERVED2 = 15, /* reserved */ - PGP_PTAG_CT_RESERVED3 = 16, /* reserved */ - PGP_PTAG_CT_USER_ATTR = 17, /* User Attribute Packet */ - PGP_PTAG_CT_SE_IP_DATA = 18, /* Sym. Encrypted and Integrity - * Protected Data Packet */ - PGP_PTAG_CT_MDC = 19, /* Modification Detection Code Packet */ - - PGP_PARSER_PTAG = 0x100,/* Internal Use: The packet is the "Packet - * Tag" itself - used when callback sends - * back the PTag. */ - PGP_PTAG_RAW_SS = 0x101,/* Internal Use: content is raw sig subtag */ - PGP_PTAG_SS_ALL = 0x102,/* Internal Use: select all subtags */ - PGP_PARSER_PACKET_END = 0x103, - - /* signature subpackets (0x200-2ff) (type+0x200) */ - /* only those we can parse are listed here */ - PGP_PTAG_SIG_SUBPKT_BASE = 0x200, /* Base for signature - * subpacket types - All - * signature type values - * are relative to this - * value. */ - PGP_PTAG_SS_CREATION_TIME = 0x200 + 2, /* signature creation time */ - PGP_PTAG_SS_EXPIRATION_TIME = 0x200 + 3, /* signature - * expiration time */ - - PGP_PTAG_SS_EXPORT_CERT = 0x200 + 4, /* exportable certification */ - PGP_PTAG_SS_TRUST = 0x200 + 5, /* trust signature */ - PGP_PTAG_SS_REGEXP = 0x200 + 6, /* regular expression */ - PGP_PTAG_SS_REVOCABLE = 0x200 + 7, /* revocable */ - PGP_PTAG_SS_KEY_EXPIRY = 0x200 + 9, /* key expiration - * time */ - PGP_PTAG_SS_RESERVED = 0x200 + 10, /* reserved */ - PGP_PTAG_SS_PREFERRED_SKA = 0x200 + 11, /* preferred symmetric - * algs */ - PGP_PTAG_SS_REVOCATION_KEY = 0x200 + 12, /* revocation key */ - PGP_PTAG_SS_ISSUER_KEY_ID = 0x200 + 16, /* issuer key ID */ - PGP_PTAG_SS_NOTATION_DATA = 0x200 + 20, /* notation data */ - PGP_PTAG_SS_PREFERRED_HASH = 0x200 + 21, /* preferred hash - * algs */ - PGP_PTAG_SS_PREF_COMPRESS = 0x200 + 22, /* preferred - * compression - * algorithms */ - PGP_PTAG_SS_KEYSERV_PREFS = 0x200 + 23, /* key server - * preferences */ - PGP_PTAG_SS_PREF_KEYSERV = 0x200 + 24, /* Preferred Key - * Server */ - PGP_PTAG_SS_PRIMARY_USER_ID = 0x200 + 25, /* primary User ID */ - PGP_PTAG_SS_POLICY_URI = 0x200 + 26, /* Policy URI */ - PGP_PTAG_SS_KEY_FLAGS = 0x200 + 27, /* key flags */ - PGP_PTAG_SS_SIGNERS_USER_ID = 0x200 + 28, /* Signer's User ID */ - PGP_PTAG_SS_REVOCATION_REASON = 0x200 + 29, /* reason for - * revocation */ - PGP_PTAG_SS_FEATURES = 0x200 + 30, /* features */ - PGP_PTAG_SS_SIGNATURE_TARGET = 0x200 + 31, /* signature target */ - PGP_PTAG_SS_EMBEDDED_SIGNATURE = 0x200 + 32, /* embedded signature */ - - PGP_PTAG_SS_USERDEFINED00 = 0x200 + 100, /* internal or - * user-defined */ - PGP_PTAG_SS_USERDEFINED01 = 0x200 + 101, - PGP_PTAG_SS_USERDEFINED02 = 0x200 + 102, - PGP_PTAG_SS_USERDEFINED03 = 0x200 + 103, - PGP_PTAG_SS_USERDEFINED04 = 0x200 + 104, - PGP_PTAG_SS_USERDEFINED05 = 0x200 + 105, - PGP_PTAG_SS_USERDEFINED06 = 0x200 + 106, - PGP_PTAG_SS_USERDEFINED07 = 0x200 + 107, - PGP_PTAG_SS_USERDEFINED08 = 0x200 + 108, - PGP_PTAG_SS_USERDEFINED09 = 0x200 + 109, - PGP_PTAG_SS_USERDEFINED10 = 0x200 + 110, - - /* pseudo content types */ - PGP_PTAG_CT_LITDATA_HEADER = 0x300, - PGP_PTAG_CT_LITDATA_BODY = 0x300 + 1, - PGP_PTAG_CT_SIGNATURE_HEADER = 0x300 + 2, - PGP_PTAG_CT_SIGNATURE_FOOTER = 0x300 + 3, - PGP_PTAG_CT_ARMOUR_HEADER = 0x300 + 4, - PGP_PTAG_CT_ARMOUR_TRAILER = 0x300 + 5, - PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER = 0x300 + 6, - PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY = 0x300 + 7, - PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER = 0x300 + 8, - PGP_PTAG_CT_UNARMOURED_TEXT = 0x300 + 9, - PGP_PTAG_CT_ENCRYPTED_SECRET_KEY = 0x300 + 10, /* In this case the - * algorithm specific - * fields will not be - * initialised */ - PGP_PTAG_CT_SE_DATA_HEADER = 0x300 + 11, - PGP_PTAG_CT_SE_DATA_BODY = 0x300 + 12, - PGP_PTAG_CT_SE_IP_DATA_HEADER = 0x300 + 13, - PGP_PTAG_CT_SE_IP_DATA_BODY = 0x300 + 14, - PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY = 0x300 + 15, - - /* commands to the callback */ - PGP_GET_PASSPHRASE = 0x400, - PGP_GET_SECKEY = 0x400 + 1, - - /* Errors */ - PGP_PARSER_ERROR = 0x500, /* Internal Use: Parser Error */ - PGP_PARSER_ERRCODE = 0x500 + 1 /* Internal Use: Parser Error - * with errcode returned */ -} pgp_content_enum; - -enum { - PGP_REVOCATION_NO_REASON = 0, - PGP_REVOCATION_SUPERSEDED = 1, - PGP_REVOCATION_COMPROMISED = 2, - PGP_REVOCATION_RETIRED = 3, - PGP_REVOCATION_NO_LONGER_VALID = 0x20 -}; - -/** Structure to hold one error code */ -typedef struct { - pgp_errcode_t errcode; -} pgp_parser_errcode_t; - -/** Structure to hold one packet tag. - * \see RFC4880 4.2 - */ -typedef struct { - unsigned new_format; /* Whether this packet tag is new - * (1) or old format (0) */ - unsigned type; /* content_tag value - See - * #pgp_content_enum for meanings */ - pgp_ptag_of_lt_t length_type; /* Length type (#pgp_ptag_of_lt_t) - * - only if this packet tag is old - * format. Set to 0 if new format. */ - unsigned length; /* The length of the packet. This value - * is set when we read and compute the length - * information, not at the same moment we - * create the packet tag structure. Only - * defined if #readc is set. *//* XXX: Ben, is this correct? */ - unsigned position; /* The position (within the - * current reader) of the packet */ - unsigned size; /* number of bits */ -} pgp_ptag_t; - -/** Public Key Algorithm Numbers. - * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP. - * - * This lists algorithm numbers for public key algorithms. - * - * \see RFC4880 9.1 - */ -typedef enum { - PGP_PKA_NOTHING = 0, /* No PKA */ - PGP_PKA_RSA = 1, /* RSA (Encrypt or Sign) */ - PGP_PKA_RSA_ENCRYPT_ONLY = 2, /* RSA Encrypt-Only (deprecated - - * \see RFC4880 13.5) */ - PGP_PKA_RSA_SIGN_ONLY = 3, /* RSA Sign-Only (deprecated - - * \see RFC4880 13.5) */ - PGP_PKA_ELGAMAL = 16, /* Elgamal (Encrypt-Only) */ - PGP_PKA_DSA = 17, /* DSA (Digital Signature Algorithm) */ - PGP_PKA_RESERVED_ELLIPTIC_CURVE = 18, /* Reserved for Elliptic - * Curve */ - PGP_PKA_RESERVED_ECDSA = 19, /* Reserved for ECDSA */ - PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20, /* Deprecated. */ - PGP_PKA_RESERVED_DH = 21, /* Reserved for Diffie-Hellman - * (X9.42, as defined for - * IETF-S/MIME) */ - PGP_PKA_PRIVATE00 = 100,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE01 = 101,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE02 = 102,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE03 = 103,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE04 = 104,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE05 = 105,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE06 = 106,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE07 = 107,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE08 = 108,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE09 = 109,/* Private/Experimental Algorithm */ - PGP_PKA_PRIVATE10 = 110 /* Private/Experimental Algorithm */ -} pgp_pubkey_alg_t; - -/** Structure to hold one DSA public key params. - * - * \see RFC4880 5.5.2 - */ -typedef struct { - BIGNUM *p; /* DSA prime p */ - BIGNUM *q; /* DSA group order q */ - BIGNUM *g; /* DSA group generator g */ - BIGNUM *y; /* DSA public key value y (= g^x mod p - * with x being the secret) */ -} pgp_dsa_pubkey_t; - -/** Structure to hold an RSA public key. - * - * \see RFC4880 5.5.2 - */ -typedef struct { - BIGNUM *n; /* RSA public modulus n */ - BIGNUM *e; /* RSA public encryption exponent e */ -} pgp_rsa_pubkey_t; - -/** Structure to hold an ElGamal public key params. - * - * \see RFC4880 5.5.2 - */ -typedef struct { - BIGNUM *p; /* ElGamal prime p */ - BIGNUM *g; /* ElGamal group generator g */ - BIGNUM *y; /* ElGamal public key value y (= g^x mod p - * with x being the secret) */ -} pgp_elgamal_pubkey_t; - -/** Version. - * OpenPGP has two different protocol versions: version 3 and version 4. - * - * \see RFC4880 5.2 - */ -typedef enum { - PGP_V2 = 2, /* Version 2 (essentially the same as v3) */ - PGP_V3 = 3, /* Version 3 */ - PGP_V4 = 4 /* Version 4 */ -} pgp_version_t; - -/** Structure to hold a pgp public key */ -typedef struct { - pgp_version_t version;/* version of the key (v3, v4...) */ - time_t birthtime; - time_t duration; - /* validity period of the key in days since - * creation. A value of 0 has a special meaning - * indicating this key does not expire. Only used with - * v3 keys. */ - unsigned days_valid; /* v4 duration */ - pgp_pubkey_alg_t alg; /* Public Key Algorithm type */ - union { - pgp_dsa_pubkey_t dsa; /* A DSA public key */ - pgp_rsa_pubkey_t rsa; /* An RSA public key */ - pgp_elgamal_pubkey_t elgamal; /* An ElGamal public key */ - } key; /* Public Key Parameters */ -} pgp_pubkey_t; - -/** Structure to hold data for one RSA secret key - */ -typedef struct { - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *u; -} pgp_rsa_seckey_t; - -/** pgp_dsa_seckey_t */ -typedef struct { - BIGNUM *x; -} pgp_dsa_seckey_t; - -/** pgp_elgamal_seckey_t */ -typedef struct { - BIGNUM *x; -} pgp_elgamal_seckey_t; - -/** s2k_usage_t - */ -typedef enum { - PGP_S2KU_NONE = 0, - PGP_S2KU_ENCRYPTED_AND_HASHED = 254, - PGP_S2KU_ENCRYPTED = 255 -} pgp_s2k_usage_t; - -/** s2k_specifier_t - */ -typedef enum { - PGP_S2KS_SIMPLE = 0, - PGP_S2KS_SALTED = 1, - PGP_S2KS_ITERATED_AND_SALTED = 3 -} pgp_s2k_specifier_t; - -/** Symmetric Key Algorithm Numbers. - * OpenPGP assigns a unique Algorithm Number to each algorithm that is - * part of OpenPGP. - * - * This lists algorithm numbers for symmetric key algorithms. - * - * \see RFC4880 9.2 - */ -typedef enum { - PGP_SA_PLAINTEXT = 0, /* Plaintext or unencrypted data */ - PGP_SA_IDEA = 1, /* IDEA */ - PGP_SA_TRIPLEDES = 2, /* TripleDES */ - PGP_SA_CAST5 = 3, /* CAST5 */ - PGP_SA_BLOWFISH = 4, /* Blowfish */ - PGP_SA_AES_128 = 7, /* AES with 128-bit key (AES) */ - PGP_SA_AES_192 = 8, /* AES with 192-bit key */ - PGP_SA_AES_256 = 9, /* AES with 256-bit key */ - PGP_SA_TWOFISH = 10, /* Twofish with 256-bit key (TWOFISH) */ - PGP_SA_CAMELLIA_128 = 100, /* Camellia with 128-bit key (CAMELLIA) */ - PGP_SA_CAMELLIA_192 = 101, /* Camellia with 192-bit key */ - PGP_SA_CAMELLIA_256 = 102 /* Camellia with 256-bit key */ -} pgp_symm_alg_t; - -#define PGP_SA_DEFAULT_CIPHER PGP_SA_CAST5 - -/** Hashing Algorithm Numbers. - * OpenPGP assigns a unique Algorithm Number to each algorithm that is - * part of OpenPGP. - * - * This lists algorithm numbers for hash algorithms. - * - * \see RFC4880 9.4 - */ -typedef enum { - PGP_HASH_UNKNOWN = -1, /* used to indicate errors */ - PGP_HASH_MD5 = 1, /* MD5 */ - PGP_HASH_SHA1 = 2, /* SHA-1 */ - PGP_HASH_RIPEMD = 3, /* RIPEMD160 */ - - PGP_HASH_SHA256 = 8, /* SHA256 */ - PGP_HASH_SHA384 = 9, /* SHA384 */ - PGP_HASH_SHA512 = 10, /* SHA512 */ - PGP_HASH_SHA224 = 11 /* SHA224 */ -} pgp_hash_alg_t; - -#define PGP_DEFAULT_HASH_ALGORITHM PGP_HASH_SHA256 - -void pgp_calc_mdc_hash(const uint8_t *, - const size_t, - const uint8_t *, - const unsigned, - uint8_t *); -unsigned pgp_is_hash_alg_supported(const pgp_hash_alg_t *); - -/* Maximum block size for symmetric crypto */ -#define PGP_MAX_BLOCK_SIZE 16 - -/* Maximum key size for symmetric crypto */ -#define PGP_MAX_KEY_SIZE 32 - -/* Salt size for hashing */ -#define PGP_SALT_SIZE 8 - -/* Max hash size */ -#define PGP_MAX_HASH_SIZE 64 - -/** pgp_seckey_t - */ -typedef struct pgp_seckey_t { - pgp_pubkey_t pubkey; /* public key */ - pgp_s2k_usage_t s2k_usage; - pgp_s2k_specifier_t s2k_specifier; - pgp_symm_alg_t alg; /* symmetric alg */ - pgp_hash_alg_t hash_alg; /* hash algorithm */ - uint8_t salt[PGP_SALT_SIZE]; - unsigned octetc; - uint8_t iv[PGP_MAX_BLOCK_SIZE]; - union { - pgp_rsa_seckey_t rsa; - pgp_dsa_seckey_t dsa; - pgp_elgamal_seckey_t elgamal; - } key; - unsigned checksum; - uint8_t *checkhash; -} pgp_seckey_t; - -/** Signature Type. - * OpenPGP defines different signature types that allow giving - * different meanings to signatures. Signature types include 0x10 for - * generitc User ID certifications (used when Ben signs Weasel's key), - * Subkey binding signatures, document signatures, key revocations, - * etc. - * - * Different types are used in different places, and most make only - * sense in their intended location (for instance a subkey binding has - * no place on a UserID). - * - * \see RFC4880 5.2.1 - */ -typedef enum { - PGP_SIG_BINARY = 0x00, /* Signature of a binary document */ - PGP_SIG_TEXT = 0x01, /* Signature of a canonical text document */ - PGP_SIG_STANDALONE = 0x02, /* Standalone signature */ - - PGP_CERT_GENERIC = 0x10,/* Generic certification of a User ID and - * Public Key packet */ - PGP_CERT_PERSONA = 0x11,/* Persona certification of a User ID and - * Public Key packet */ - PGP_CERT_CASUAL = 0x12, /* Casual certification of a User ID and - * Public Key packet */ - PGP_CERT_POSITIVE = 0x13, /* Positive certification of a - * User ID and Public Key packet */ - - PGP_SIG_SUBKEY = 0x18, /* Subkey Binding Signature */ - PGP_SIG_PRIMARY = 0x19, /* Primary Key Binding Signature */ - PGP_SIG_DIRECT = 0x1f, /* Signature directly on a key */ - - PGP_SIG_REV_KEY = 0x20, /* Key revocation signature */ - PGP_SIG_REV_SUBKEY = 0x28, /* Subkey revocation signature */ - PGP_SIG_REV_CERT = 0x30,/* Certification revocation signature */ - - PGP_SIG_TIMESTAMP = 0x40, /* Timestamp signature */ - - PGP_SIG_3RD_PARTY = 0x50/* Third-Party Confirmation signature */ -} pgp_sig_type_t; - -/** Struct to hold params of an RSA signature */ -typedef struct pgp_rsa_sig_t { - BIGNUM *sig; /* the signature value (m^d % n) */ -} pgp_rsa_sig_t; - -/** Struct to hold params of a DSA signature */ -typedef struct pgp_dsa_sig_t { - BIGNUM *r; /* DSA value r */ - BIGNUM *s; /* DSA value s */ -} pgp_dsa_sig_t; - -/** pgp_elgamal_signature_t */ -typedef struct pgp_elgamal_sig_t { - BIGNUM *r; - BIGNUM *s; -} pgp_elgamal_sig_t; - -#define PGP_KEY_ID_SIZE 8 -#define PGP_FINGERPRINT_SIZE 20 - -/** Struct to hold a signature packet. - * - * \see RFC4880 5.2.2 - * \see RFC4880 5.2.3 - */ -typedef struct pgp_sig_info_t { - pgp_version_t version;/* signature version number */ - pgp_sig_type_t type; /* signature type value */ - time_t birthtime; /* creation time of the signature */ - time_t duration; /* number of seconds it's valid for */ - time_t key_expiry; /* number of seconds key is valid for */ - uint8_t key_flags; - uint8_t signer_id[PGP_KEY_ID_SIZE]; /* Eight-octet key ID - * of signer */ - pgp_pubkey_alg_t key_alg; /* public key algorithm number */ - pgp_hash_alg_t hash_alg; /* hashing algorithm number */ - union { - pgp_rsa_sig_t rsa; /* An RSA Signature */ - pgp_dsa_sig_t dsa; /* A DSA Signature */ - pgp_elgamal_sig_t elgamal; /* deprecated */ - pgp_data_t unknown; /* private or experimental */ - } sig; /* signature params */ - size_t v4_hashlen; - uint8_t *v4_hashed; - unsigned birthtime_set:1; - unsigned signer_id_set:1; - unsigned duration_set:1; - unsigned key_expiry_set:1; - unsigned key_flags_set:1; - unsigned primary_userid:1; -} pgp_sig_info_t; - -typedef enum { - PGP_KEYFLAG_CERT_KEYS = 0x01, - PGP_KEYFLAG_SIGN_DATA = 0x02, - PGP_KEYFLAG_ENC_COMM = 0x04, - PGP_KEYFLAG_ENC_STORAGE = 0x08, - PGP_KEYFLAG_SPLIT = 0x10, - PGP_KEYFLAG_AUTH = 0x20, - PGP_KEYFLAG_GROUP = 0x80 -} pgp_key_flags_t; - -/** Struct used when parsing a signature */ -typedef struct pgp_sig_t { - pgp_sig_info_t info; /* The signature information */ - /* The following fields are only used while parsing the signature */ - uint8_t hash2[2]; /* high 2 bytes of hashed value */ - size_t v4_hashstart; /* only valid if accumulate is set */ - pgp_hash_t *hash; /* the hash filled in for the data so far */ -} pgp_sig_t; - -/** The raw bytes of a signature subpacket */ - -typedef struct pgp_ss_raw_t { - pgp_content_enum tag; - size_t length; - uint8_t *raw; -} pgp_ss_raw_t; - -/** Signature Subpacket : Trust Level */ - -typedef struct pgp_ss_trust_t { - uint8_t level; /* Trust Level */ - uint8_t amount; /* Amount */ -} pgp_ss_trust_t; - -/** Signature Subpacket : Notation Data */ -typedef struct pgp_ss_notation_t { - pgp_data_t flags; - pgp_data_t name; - pgp_data_t value; -} pgp_ss_notation_t; - -/** Signature Subpacket : Signature Target */ -typedef struct pgp_ss_sig_target_t { - pgp_pubkey_alg_t pka_alg; - pgp_hash_alg_t hash_alg; - pgp_data_t hash; -} pgp_ss_sig_target_t; - -/** pgp_subpacket_t */ -typedef struct pgp_subpacket_t { - size_t length; - uint8_t *raw; -} pgp_subpacket_t; - -/** Types of Compression */ -typedef enum { - PGP_C_NONE = 0, - PGP_C_ZIP = 1, - PGP_C_ZLIB = 2, - PGP_C_BZIP2 = 3 -} pgp_compression_type_t; - -/** pgp_one_pass_sig_t */ -typedef struct { - uint8_t version; - pgp_sig_type_t sig_type; - pgp_hash_alg_t hash_alg; - pgp_pubkey_alg_t key_alg; - uint8_t keyid[PGP_KEY_ID_SIZE]; - unsigned nested; -} pgp_one_pass_sig_t; - -/** Signature Subpacket : Revocation Key */ -typedef struct { - uint8_t class; - uint8_t algid; - uint8_t fingerprint[PGP_FINGERPRINT_SIZE]; -} pgp_ss_revocation_key_t; - -/** Signature Subpacket : Revocation Reason */ -typedef struct { - uint8_t code; - char *reason; -} pgp_ss_revocation_t; - -/** litdata_type_t */ -typedef enum { - PGP_LDT_BINARY = 'b', - PGP_LDT_TEXT = 't', - PGP_LDT_UTF8 = 'u', - PGP_LDT_LOCAL = 'l', - PGP_LDT_LOCAL2 = '1' -} pgp_litdata_enum; - -/** pgp_litdata_header_t */ -typedef struct { - pgp_litdata_enum format; - char filename[256]; - time_t mtime; -} pgp_litdata_header_t; - -/** pgp_litdata_body_t */ -typedef struct { - unsigned length; - uint8_t *data; - void *mem; /* pgp_memory_t pointer */ -} pgp_litdata_body_t; - -/** pgp_header_var_t */ -typedef struct { - char *key; - char *value; -} pgp_header_var_t; - -/** pgp_headers_t */ -typedef struct { - pgp_header_var_t *headers; - unsigned headerc; -} pgp_headers_t; - -/** pgp_armour_header_t */ -typedef struct { - const char *type; - pgp_headers_t headers; -} pgp_armour_header_t; - -/** pgp_fixed_body_t */ -typedef struct pgp_fixed_body_t { - unsigned length; - uint8_t data[8192]; /* \todo fix hard-coded value? */ -} pgp_fixed_body_t; - -/** pgp_dyn_body_t */ -typedef struct pgp_dyn_body_t { - unsigned length; - uint8_t *data; -} pgp_dyn_body_t; - -enum { - PGP_SE_IP_DATA_VERSION = 1, - PGP_PKSK_V3 = 3 -}; - -/** pgp_pk_sesskey_params_rsa_t */ -typedef struct { - BIGNUM *encrypted_m; - BIGNUM *m; -} pgp_pk_sesskey_params_rsa_t; - -/** pgp_pk_sesskey_params_elgamal_t */ -typedef struct { - BIGNUM *g_to_k; - BIGNUM *encrypted_m; -} pgp_pk_sesskey_params_elgamal_t; - -/** pgp_pk_sesskey_params_t */ -typedef union { - pgp_pk_sesskey_params_rsa_t rsa; - pgp_pk_sesskey_params_elgamal_t elgamal; -} pgp_pk_sesskey_params_t; - -/** pgp_pk_sesskey_t */ -typedef uint8_t key_id_t[PGP_KEY_ID_SIZE]; -typedef struct { - unsigned version; - key_id_t key_id; - pgp_pubkey_alg_t alg; - pgp_pk_sesskey_params_t params; - pgp_symm_alg_t symm_alg; - uint8_t key[PGP_MAX_KEY_SIZE]; - uint16_t checksum; -} pgp_pk_sesskey_t; - -/** pgp_seckey_passphrase_t */ -typedef struct { - const pgp_seckey_t *seckey; - char **passphrase; /* point somewhere that gets filled - * in to work around constness of - * content */ -} pgp_seckey_passphrase_t; - -/** pgp_get_seckey_t */ -typedef struct { - const pgp_seckey_t **seckey; - const pgp_pk_sesskey_t *pk_sesskey; -} pgp_get_seckey_t; - -/** pgp_parser_union_content_t */ -typedef union { - const char *error; - pgp_parser_errcode_t errcode; - pgp_ptag_t ptag; - pgp_pubkey_t pubkey; - pgp_data_t trust; - uint8_t *userid; - pgp_data_t userattr; - pgp_sig_t sig; - pgp_ss_raw_t ss_raw; - pgp_ss_trust_t ss_trust; - unsigned ss_revocable; - time_t ss_time; - uint8_t ss_issuer[PGP_KEY_ID_SIZE]; - pgp_ss_notation_t ss_notation; - pgp_subpacket_t packet; - pgp_compression_type_t compressed; - pgp_one_pass_sig_t one_pass_sig; - pgp_data_t ss_skapref; - pgp_data_t ss_hashpref; - pgp_data_t ss_zpref; - pgp_data_t ss_key_flags; - pgp_data_t ss_key_server_prefs; - unsigned ss_primary_userid; - char *ss_regexp; - char *ss_policy; - char *ss_keyserv; - pgp_ss_revocation_key_t ss_revocation_key; - pgp_data_t ss_userdef; - pgp_data_t ss_unknown; - pgp_litdata_header_t litdata_header; - pgp_litdata_body_t litdata_body; - pgp_dyn_body_t mdc; - pgp_data_t ss_features; - pgp_ss_sig_target_t ss_sig_target; - pgp_data_t ss_embedded_sig; - pgp_ss_revocation_t ss_revocation; - pgp_seckey_t seckey; - uint8_t *ss_signer; - pgp_armour_header_t armour_header; - const char *armour_trailer; - pgp_headers_t cleartext_head; - pgp_fixed_body_t cleartext_body; - struct pgp_hash_t *cleartext_trailer; - pgp_dyn_body_t unarmoured_text; - pgp_pk_sesskey_t pk_sesskey; - pgp_seckey_passphrase_t skey_passphrase; - unsigned se_ip_data_header; - pgp_dyn_body_t se_ip_data_body; - pgp_fixed_body_t se_data_body; - pgp_get_seckey_t get_seckey; -} pgp_contents_t; - -/** pgp_packet_t */ -struct pgp_packet_t { - pgp_content_enum tag; /* type of contents */ - uint8_t critical; /* for sig subpackets */ - pgp_contents_t u; /* union for contents */ -}; - -/** pgp_fingerprint_t */ -typedef struct { - uint8_t fingerprint[PGP_FINGERPRINT_SIZE]; - unsigned length; - pgp_hash_alg_t hashtype; -} pgp_fingerprint_t; - -int pgp_keyid(uint8_t *, const size_t, const pgp_pubkey_t *, pgp_hash_alg_t); -int pgp_fingerprint(pgp_fingerprint_t *, const pgp_pubkey_t *, pgp_hash_alg_t); - -void pgp_finish(void); -void pgp_pubkey_free(pgp_pubkey_t *); -int pgp_pubkey_dup(pgp_pubkey_t *,pgp_pubkey_t *); -void pgp_userid_free(uint8_t **); -void pgp_data_free(pgp_data_t *); -void pgp_sig_free(pgp_sig_t *); -void pgp_ss_notation_free(pgp_ss_notation_t *); -void pgp_ss_revocation_free(pgp_ss_revocation_t *); -void pgp_ss_sig_target_free(pgp_ss_sig_target_t *); - -void pgp_subpacket_free(pgp_subpacket_t *); -void pgp_parser_content_free(pgp_packet_t *); -void pgp_seckey_free(pgp_seckey_t *); -int pgp_seckey_dup(pgp_seckey_t *,pgp_seckey_t *); -void pgp_pk_sesskey_free(pgp_pk_sesskey_t *); - -#define DYNARRAY(type, arr) \ - unsigned arr##c; unsigned arr##vsize; type *arr##s - -#define EXPAND_ARRAY(str, arr) do { \ - if (str->arr##c == str->arr##vsize) { \ - void *__newarr; \ - char *__newarrc; \ - unsigned __newsize; \ - __newsize = (str->arr##vsize * 2) + 10; \ - if ((__newarrc = __newarr = realloc(str->arr##s, \ - __newsize * sizeof(*str->arr##s))) == NULL) { \ - (void) fprintf(stderr, "EXPAND_ARRAY - bad realloc\n"); \ - } else { \ - (void) memset(&__newarrc[str->arr##vsize * sizeof(*str->arr##s)], \ - 0x0, (__newsize - str->arr##vsize) * sizeof(*str->arr##s)); \ - str->arr##s = __newarr; \ - str->arr##vsize = __newsize; \ - } \ - } \ -} while(/*CONSTCOND*/0) - -#define FREE_ARRAY(str, arr) do { \ - if (str->arr##s) { \ - free(str->arr##s); \ - str->arr##s = NULL; \ - str->arr##vsize = 0; \ - str->arr##c = 0; \ - } \ -} while(/*CONSTCOND*/0) - -#define INIT_ARRAY(str, arr) do { \ - str->arr##s = NULL; \ - str->arr##vsize = 0; \ - str->arr##c = 0; \ -} while(/*CONSTCOND*/0) - -/** pgp_keydata_key_t - */ -typedef union { - pgp_pubkey_t pubkey; - pgp_seckey_t seckey; -} pgp_keydata_key_t; - -/** userid signature subpackets */ -typedef struct pgp_uidsig_t { - uint32_t uid; /* index in userid array in key */ - pgp_sig_info_t siginfo; - uint8_t trustlevel; /* level of trust */ - uint8_t trustamount; /* amount of trust */ - pgp_subpacket_t packet; -} pgp_uidsig_t; - -/** subkey signature subpackets */ -typedef struct pgp_subkeysig_t { - uint32_t subkey; /* index of subkey in array */ - pgp_sig_info_t siginfo; - pgp_subpacket_t packet; -} pgp_subkeysig_t; - -typedef struct pgp_subkey_t { - pgp_keydata_key_t key; /* pubkey/seckey data */ - uint8_t id[PGP_KEY_ID_SIZE]; -} pgp_subkey_t; - -typedef struct pgp_directsig_t { - pgp_sig_info_t siginfo; - pgp_subpacket_t packet; -} pgp_directsig_t; - -/* describes a user's key */ -struct pgp_key_t { - pgp_content_enum type; /* type of key */ - pgp_keydata_key_t key; /* pubkey/seckey data */ - - DYNARRAY(pgp_directsig_t, directsig); /* direct signatures */ - - DYNARRAY(uint8_t *, uid); /* array of user ids */ - DYNARRAY(pgp_uidsig_t, uidsig); /* array of signature for user ids */ - - /* TODO user attributes */ - - DYNARRAY(pgp_subkey_t, subkey); /* array of subkeys */ - DYNARRAY(pgp_subkeysig_t, subkeysig); /* array of sigs for subkeys */ - - uint8_t pubkeyid[PGP_KEY_ID_SIZE]; - pgp_fingerprint_t pubkeyfpr; /* pgp signature fingerprint */ -}; - -typedef enum { - PGP_VALID, - PGP_WEAK, - PGP_TOOSHORT, - PGP_INVALID, - PGP_EXPIRED, - PGP_REVOKED -} pgp_key_rating_t; - -#define MDC_PKT_TAG 0xd3 -#endif /* PACKET_H_ */ diff --git a/netpgp/netpgp/readerwriter.h b/netpgp/netpgp/readerwriter.h deleted file mode 100644 index 51029f5f9c753006b7f0ca76cf4c0d63a4c406d7..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/readerwriter.h +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef READERWRITER_H_ -#define READERWRITER_H_ - -#include "create.h" - -#include "memory.h" - -/* if this is defined, we'll use mmap in preference to file ops */ -#define USE_MMAP_FOR_FILES 1 - -void pgp_reader_set_fd(pgp_stream_t *, int); -void pgp_reader_set_mmap(pgp_stream_t *, int); -void pgp_reader_set_memory(pgp_stream_t *, const void *, size_t); - -/* Do a sum mod 65536 of all bytes read (as needed for secret keys) */ -void pgp_reader_push_sum16(pgp_stream_t *); -uint16_t pgp_reader_pop_sum16(pgp_stream_t *); - -void pgp_reader_push_se_ip_data(pgp_stream_t *, pgp_crypt_t *, - pgp_region_t *); -void pgp_reader_pop_se_ip_data(pgp_stream_t *); - -/* */ -unsigned pgp_write_mdc(pgp_output_t *, const uint8_t *); -unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *, - const unsigned, - pgp_crypt_t *); -void pgp_push_enc_crypt(pgp_output_t *, pgp_crypt_t *); -int pgp_push_enc_se_ip(pgp_output_t *, const pgp_keyring_t *, const char *, unsigned); - -/* Secret Key checksum */ -void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *); -unsigned pgp_pop_skey_checksum_writer(pgp_output_t *); - - -/* memory writing */ -void pgp_setup_memory_write(pgp_output_t **, pgp_memory_t **, size_t); -void pgp_teardown_memory_write(pgp_output_t *, pgp_memory_t *); - -/* memory reading */ -void pgp_setup_memory_read(pgp_io_t *, - pgp_stream_t **, - pgp_memory_t *, - void *, - pgp_cb_ret_t callback(const pgp_packet_t *, - pgp_cbdata_t *), - unsigned); -void pgp_teardown_memory_read(pgp_stream_t *, pgp_memory_t *); - -/* file writing */ -int pgp_setup_file_write(pgp_output_t **, const char *, unsigned); -void pgp_teardown_file_write(pgp_output_t *, int); - -/* file appending */ -int pgp_setup_file_append(pgp_output_t **, const char *); -void pgp_teardown_file_append(pgp_output_t *, int); - -/* file reading */ -int pgp_setup_file_read(pgp_io_t *, - pgp_stream_t **, - const char *, - void *, - pgp_cb_ret_t callback(const pgp_packet_t *, - pgp_cbdata_t *), - unsigned); -void pgp_teardown_file_read(pgp_stream_t *, int); - -unsigned pgp_reader_set_accumulate(pgp_stream_t *, unsigned); - -/* useful callbacks */ -pgp_cb_ret_t pgp_litdata_cb(const pgp_packet_t *, pgp_cbdata_t *); -pgp_cb_ret_t pgp_pk_sesskey_cb(const pgp_packet_t *, pgp_cbdata_t *); -pgp_cb_ret_t pgp_get_seckey_cb(const pgp_packet_t *, pgp_cbdata_t *); - -int pgp_getpassphrase(void *, char *, size_t); - -#endif /* READERWRITER_H_ */ diff --git a/netpgp/netpgp/signature.h b/netpgp/netpgp/signature.h deleted file mode 100644 index bb8bc4d046605e97ad12acc52a91a1bca11e7453..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/signature.h +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef SIGNATURE_H_ -#define SIGNATURE_H_ - -#include <sys/types.h> - -#include <inttypes.h> - -#include "packet.h" -#include "create.h" -#include "memory.h" - -typedef struct pgp_create_sig_t pgp_create_sig_t; - -pgp_create_sig_t *pgp_create_sig_new(void); -void pgp_create_sig_delete(pgp_create_sig_t *); - -unsigned pgp_check_useridcert_sig(const pgp_pubkey_t *, - const uint8_t *, - const pgp_sig_t *, - const pgp_pubkey_t *); -unsigned pgp_check_userattrcert_sig(const pgp_pubkey_t *, - const pgp_data_t *, - const pgp_sig_t *, - const pgp_pubkey_t *); -unsigned pgp_check_subkey_sig(const pgp_pubkey_t *, - const pgp_pubkey_t *, - const pgp_sig_t *, - const pgp_pubkey_t *); -unsigned pgp_check_direct_sig(const pgp_pubkey_t *, - const pgp_sig_t *, - const pgp_pubkey_t *); -unsigned pgp_check_hash_sig(pgp_hash_t *, - const pgp_sig_t *, - const pgp_pubkey_t *); -void pgp_sig_start_key_sig(pgp_create_sig_t *, - const pgp_pubkey_t *, - const pgp_pubkey_t * subkey, // parameter added by Delta Chat to allow subkey binding signatures, EDIT BY MR (bp) - const uint8_t *, - pgp_sig_type_t); -void pgp_start_sig(pgp_create_sig_t *, - const pgp_seckey_t *, - const pgp_hash_alg_t, - const pgp_sig_type_t); - -void pgp_sig_add_data(pgp_create_sig_t *, const void *, size_t); -pgp_hash_t *pgp_sig_get_hash(pgp_create_sig_t *); -unsigned pgp_end_hashed_subpkts(pgp_create_sig_t *); -unsigned pgp_write_sig(pgp_output_t *, pgp_create_sig_t *, - const pgp_pubkey_t *, const pgp_seckey_t *); -unsigned pgp_add_issuer_keyid(pgp_create_sig_t *, - const uint8_t *); -void pgp_add_primary_userid(pgp_create_sig_t *, unsigned); - -unsigned -pgp_add_creation_time(pgp_create_sig_t *sig, time_t when); -unsigned -pgp_add_sig_expiration_time(pgp_create_sig_t *sig, time_t duration); -unsigned -pgp_add_key_expiration_time(pgp_create_sig_t *sig, time_t duration); -unsigned -pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags); -unsigned -pgp_add_key_prefs(pgp_create_sig_t *sig); -unsigned -pgp_add_key_features(pgp_create_sig_t *sig); - -/* Standard Interface */ -unsigned pgp_sign_file(pgp_io_t *, - const char *, - const char *, - const pgp_seckey_t *, - const char *, - const time_t, - const time_t, - const unsigned, - const unsigned, - const unsigned); - -int pgp_sign_detached(pgp_io_t *, - const char *, - char *, - const pgp_seckey_t *, - const char *, - const time_t, - const time_t, - const unsigned, - const unsigned); - -/* armoured stuff */ -unsigned pgp_crc24(unsigned, uint8_t); - -void pgp_reader_push_dearmour(pgp_stream_t *); - -void pgp_reader_pop_dearmour(pgp_stream_t *); -unsigned pgp_writer_push_clearsigned(pgp_output_t *, pgp_create_sig_t *); -void pgp_writer_push_armor_msg(pgp_output_t *); - -typedef enum { - PGP_PGP_MESSAGE = 1, - PGP_PGP_PUBLIC_KEY_BLOCK, - PGP_PGP_PRIVATE_KEY_BLOCK, - PGP_PGP_MULTIPART_MESSAGE_PART_X_OF_Y, - PGP_PGP_MULTIPART_MESSAGE_PART_X, - PGP_PGP_SIGNATURE -} pgp_armor_type_t; - -#define CRC24_INIT 0xb704ceL - -unsigned pgp_writer_use_armored_sig(pgp_output_t *); - -void pgp_writer_push_armoured(pgp_output_t *, pgp_armor_type_t); - -pgp_memory_t *pgp_sign_buf(pgp_io_t *, - const void *, - const size_t, - const pgp_seckey_t *, - const time_t, - const time_t, - const char *, - const unsigned, - const unsigned); - -/** \ingroup Core_Create - * needed for signature creation - */ -struct pgp_create_sig_t { - pgp_hash_t hash; - pgp_sig_t sig; - pgp_memory_t *mem; - pgp_output_t *output; /* how to do the writing */ - unsigned hashoff; /* hashed count offset */ - unsigned hashlen; - unsigned unhashoff; -}; - -void -pgp_sig_start_key_rev(pgp_create_sig_t *sig, - const pgp_pubkey_t *key, - pgp_sig_type_t type); - -unsigned -pgp_add_revocation_reason( - pgp_create_sig_t *sig, - uint8_t code, const char *reason); - -#endif /* SIGNATURE_H_ */ diff --git a/netpgp/netpgp/types.h b/netpgp/netpgp/types.h deleted file mode 100644 index cc03f7b0735a07923397d23e8ad3c553b863eefa..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/types.h +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef TYPES_H_ -#define TYPES_H_ - -#ifdef HAVE_INTTYPES_H -#include <inttypes.h> -#endif - -typedef struct pgp_io_t { - void *outs; /* output file stream */ - void *errs; /* file stream to put error messages */ - void *res; /* file stream to put results */ -} pgp_io_t; - -/** pgp_map_t - */ -typedef struct { - int type; - const char *string; -} pgp_map_t; - -/** pgp_errcode_name_map_t */ -typedef pgp_map_t pgp_errcode_name_map_t; - -typedef struct pgp_crypt_t pgp_crypt_t; - -/** pgp_hash_t */ -typedef struct pgp_hash_t pgp_hash_t; - -/** Revocation Reason type */ -typedef uint8_t pgp_ss_rr_code_t; - -/** pgp_packet_t */ -typedef struct pgp_packet_t pgp_packet_t; - -/** Writer flags */ -typedef enum { - PGP_WF_DUMMY -} pgp_writer_flags_t; - -/** - * \ingroup Create - * Contains the required information about how to write - */ -typedef struct pgp_output_t pgp_output_t; - -#endif /* TYPES_H_ */ diff --git a/netpgp/netpgp/validate.h b/netpgp/netpgp/validate.h deleted file mode 100644 index 44455a33b033b528def746c636aca81916f0ade8..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/validate.h +++ /dev/null @@ -1,148 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef VALIDATE_H_ -#define VALIDATE_H_ 1 - -/** Struct used with the validate_key_cb callback */ -typedef struct validate_key_cb_t{ - pgp_content_enum type; /* type of key */ - pgp_keydata_key_t key; /* pubkey/seckey data */ - pgp_keydata_key_t subkey; - uint8_t pubkeyid[PGP_KEY_ID_SIZE]; - enum { - LS_UNKNOWN = 0, - LS_ATTRIBUTE, - LS_ID, - LS_SUBKEY, - LS_PRIMARY, - } last_seen; - - uint8_t *userid; - pgp_data_t userattr; - uint8_t hash[PGP_MAX_HASH_SIZE]; - const pgp_keyring_t *keyring; - pgp_validation_t *result; - pgp_cb_ret_t(*getpassphrase) (const pgp_packet_t *, - pgp_cbdata_t *); - - unsigned not_commited; /* tells on_valid it is first commit of that key */ - pgp_sig_info_t valid_sig_info; /* store last valid sig info */ - unsigned sig_is_valid; /* condition to call on_valid at packet end */ - pgp_cb_ret_t(*on_valid) ( /* callback for action on valid sig */ - struct validate_key_cb_t *, /* this struct */ - const pgp_subpacket_t *); /* sig packet */ - void *on_valid_args; /* pointer to argument for on_valid callback */ - -} validate_key_cb_t; - -/** Struct use with the validate_data_cb callback */ -typedef struct { - enum { - LITDATA, - SIGNED_CLEARTEXT - } type; - union { - pgp_litdata_body_t litdata_body; - pgp_fixed_body_t cleartext_body; - } data; - uint8_t hash[PGP_MAX_HASH_SIZE]; - pgp_memory_t *mem; - const pgp_keyring_t *keyring; - pgp_validation_t *result; - char *detachname; -} validate_data_cb_t; - -pgp_cb_ret_t pgp_validate_key_cb(const pgp_packet_t *, pgp_cbdata_t *); - -unsigned check_binary_sig(const uint8_t *, - const unsigned, - const pgp_sig_t *, - const pgp_pubkey_t *); - -unsigned pgp_validate_file(pgp_io_t *, - pgp_validation_t *, - const char *, - const char *, - const int, - const pgp_keyring_t *); - -unsigned pgp_validate_mem(pgp_io_t *, - pgp_validation_t *, - pgp_memory_t *, - pgp_memory_t **, - const int, - const pgp_keyring_t *); - -unsigned pgp_validate_mem_detached(pgp_io_t *, - pgp_validation_t *, - pgp_memory_t *, - pgp_memory_t **, - const int, - const pgp_keyring_t *, - pgp_memory_t *); - -pgp_cb_ret_t validate_data_cb(const pgp_packet_t *, pgp_cbdata_t *); -void pgp_free_sig_info(pgp_sig_info_t *); - -unsigned -pgp_filter_keys_fileread(pgp_io_t *io, - pgp_keyring_t *destpubring, - pgp_keyring_t *destsecring, - pgp_keyring_t *certring, - const unsigned armour, - const char *filename); - -unsigned -pgp_filter_keys_from_mem(pgp_io_t *io, - pgp_keyring_t *destpubring, - pgp_keyring_t *destsecring, - pgp_keyring_t *certring, - const unsigned armour, - pgp_memory_t *mem); -#endif /* !VALIDATE_H_ */ diff --git a/netpgp/netpgp/version.h b/netpgp/netpgp/version.h deleted file mode 100644 index 74bf76580ba357e6cf001311ff72c0ce5b596d68..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/version.h +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef VERSION_H_ -#define VERSION_H_ 1 - -#ifndef NETPGP_AUTOCONF_VERSION -#define NETPGP_AUTOCONF_VERSION PACKAGE_VERSION -#endif - -#ifndef NETPGP_MAINTAINER -#define NETPGP_MAINTAINER PACKAGE_BUGREPORT -#endif - -/* development versions have .99 suffix */ -#define NETPGP_BASE_VERSION "3.99.99" - -#define NETPGP_VERSION_CAT(a, b) "NetPGP for Delta Chat " a "/[" b "]" -#define NETPGP_VERSION_STRING \ - NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION) - -#endif /* !VERSION_H_ */ diff --git a/netpgp/netpgp/writer.h b/netpgp/netpgp/writer.h deleted file mode 100644 index 632eeeb67aab242339486f2e9943aa0a5039fd6c..0000000000000000000000000000000000000000 --- a/netpgp/netpgp/writer.h +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef WRITER_H_ -#define WRITER_H_ - -#include "types.h" -#include "packet.h" -#include "crypto.h" -#include "errors.h" -#include "keyring.h" - -/** - * \ingroup Writer - * the writer function prototype - */ - -typedef struct pgp_writer_t pgp_writer_t; -typedef unsigned pgp_writer_func_t(const uint8_t *, - unsigned, - pgp_error_t **, - pgp_writer_t *); -typedef unsigned -pgp_writer_finaliser_t(pgp_error_t **, pgp_writer_t *); -typedef void pgp_writer_destroyer_t(pgp_writer_t *); - -/** Writer settings */ -struct pgp_writer_t { - pgp_writer_func_t *writer; /* the writer itself */ - pgp_writer_finaliser_t *finaliser; /* the writer's finaliser */ - pgp_writer_destroyer_t *destroyer; /* the writer's destroyer */ - void *arg; /* writer-specific argument */ - pgp_writer_t *next; /* next writer in the stack */ - pgp_io_t *io; /* IO for errors and output */ -}; - - -void *pgp_writer_get_arg(pgp_writer_t *); - -void pgp_writer_set(pgp_output_t *, - pgp_writer_func_t *, - pgp_writer_finaliser_t *, - pgp_writer_destroyer_t *, - void *); -void pgp_writer_push(pgp_output_t *, - pgp_writer_func_t *, - pgp_writer_finaliser_t *, - pgp_writer_destroyer_t *, - void *); -void pgp_writer_pop(pgp_output_t *); -unsigned pgp_writer_passthrough(const uint8_t *, - unsigned, - pgp_error_t **, - pgp_writer_t *); - -void pgp_writer_set_fd(pgp_output_t *, int); -unsigned pgp_writer_close(pgp_output_t *); - -unsigned pgp_write(pgp_output_t *, const void *, unsigned); -unsigned pgp_write_length(pgp_output_t *, unsigned); -unsigned pgp_write_ptag(pgp_output_t *, pgp_content_enum); -unsigned pgp_write_scalar(pgp_output_t *, unsigned, unsigned); -unsigned pgp_write_mpi(pgp_output_t *, const BIGNUM *); - -void pgp_writer_info_delete(pgp_writer_t *); -unsigned pgp_writer_info_finalise(pgp_error_t **, pgp_writer_t *); - -void pgp_push_stream_enc_se_ip(pgp_output_t *, pgp_key_t *, const char *); - -void pgp_push_sum16_writer(pgp_output_t *output); - -uint16_t pgp_pop_sum16_writer(pgp_output_t *output); - -#endif /* WRITER_H_ */ diff --git a/netpgp/openssl_crypto.c b/netpgp/openssl_crypto.c deleted file mode 100644 index 2b8499ee01a8ccb426fa519f40f8cb849dd72b58..0000000000000000000000000000000000000000 --- a/netpgp/openssl_crypto.c +++ /dev/null @@ -1,1070 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#ifdef HAVE_OPENSSL_DSA_H -#include <openssl/dsa.h> -#endif - -#ifdef HAVE_OPENSSL_RSA_H -#include <openssl/rsa.h> -#endif - -#ifdef HAVE_OPENSSL_ERR_H -#include <openssl/err.h> -#endif - -#include <openssl/pem.h> -#include <openssl/evp.h> - -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "netpgp/crypto.h" -#include "netpgp/keyring.h" -#include "netpgp/readerwriter.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/netpgpdigest.h" -#include "netpgp/packet.h" -#include "netpgp/openssl11stub.h" - - -static void -test_seckey(const pgp_seckey_t *seckey) -{ - RSA *test = RSA_new(); - - RSA_set0_key(test, - BN_dup(seckey->pubkey.key.rsa.n), - BN_dup(seckey->pubkey.key.rsa.e), - BN_dup(seckey->key.rsa.d)); - - RSA_set0_factors(test, - BN_dup(seckey->key.rsa.p), - BN_dup(seckey->key.rsa.q)); - - if (RSA_check_key(test) != 1) { - (void) fprintf(stderr, - "test_seckey: RSA_check_key failed\n"); - } - RSA_free(test); -} - -static int -md5_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "md5_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) { - (void) fprintf(stderr, "md5_init: bad alloc\n"); - return 0; - } - MD5_Init(hash->data); - return 1; -} - -static void -md5_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - MD5_Update(hash->data, data, length); -} - -static unsigned -md5_finish(pgp_hash_t *hash, uint8_t *out) -{ - MD5_Final(out, hash->data); - free(hash->data); - hash->data = NULL; - return 16; -} - -static const pgp_hash_t md5 = { - PGP_HASH_MD5, - MD5_DIGEST_LENGTH, - "MD5", - md5_init, - md5_add, - md5_finish, - NULL -}; - -/** - \ingroup Core_Crypto - \brief Initialise to MD5 - \param hash Hash to initialise -*/ -void -pgp_hash_md5(pgp_hash_t *hash) -{ - *hash = md5; -} - -static int -sha1_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "sha1_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) { - (void) fprintf(stderr, "sha1_init: bad alloc\n"); - return 0; - } - SHA1_Init(hash->data); - return 1; -} - -static void -sha1_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha1_add", data, length); - } - SHA1_Update(hash->data, data, length); -} - -static unsigned -sha1_finish(pgp_hash_t *hash, uint8_t *out) -{ - SHA1_Final(out, hash->data); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha1_finish", out, PGP_SHA1_HASH_SIZE); - } - free(hash->data); - hash->data = NULL; - return PGP_SHA1_HASH_SIZE; -} - -static const pgp_hash_t sha1 = { - PGP_HASH_SHA1, - PGP_SHA1_HASH_SIZE, - "SHA1", - sha1_init, - sha1_add, - sha1_finish, - NULL -}; - -/** - \ingroup Core_Crypto - \brief Initialise to SHA1 - \param hash Hash to initialise -*/ -void -pgp_hash_sha1(pgp_hash_t *hash) -{ - *hash = sha1; -} - -static int -sha256_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "sha256_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) { - (void) fprintf(stderr, "sha256_init: bad alloc\n"); - return 0; - } - SHA256_Init(hash->data); - return 1; -} - -static void -sha256_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha256_add", data, length); - } - SHA256_Update(hash->data, data, length); -} - -static unsigned -sha256_finish(pgp_hash_t *hash, uint8_t *out) -{ - SHA256_Final(out, hash->data); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha1_finish", out, SHA256_DIGEST_LENGTH); - } - free(hash->data); - hash->data = NULL; - return SHA256_DIGEST_LENGTH; -} - -static const pgp_hash_t sha256 = { - PGP_HASH_SHA256, - SHA256_DIGEST_LENGTH, - "SHA256", - sha256_init, - sha256_add, - sha256_finish, - NULL -}; - -void -pgp_hash_sha256(pgp_hash_t *hash) -{ - *hash = sha256; -} - -/* - * SHA384 - */ -static int -sha384_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "sha384_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) { - (void) fprintf(stderr, "sha384_init: bad alloc\n"); - return 0; - } - SHA384_Init(hash->data); - return 1; -} - -static void -sha384_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha384_add", data, length); - } - SHA384_Update(hash->data, data, length); -} - -static unsigned -sha384_finish(pgp_hash_t *hash, uint8_t *out) -{ - SHA384_Final(out, hash->data); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha384_finish", out, SHA384_DIGEST_LENGTH); - } - free(hash->data); - hash->data = NULL; - return SHA384_DIGEST_LENGTH; -} - -static const pgp_hash_t sha384 = { - PGP_HASH_SHA384, - SHA384_DIGEST_LENGTH, - "SHA384", - sha384_init, - sha384_add, - sha384_finish, - NULL -}; - -void -pgp_hash_sha384(pgp_hash_t *hash) -{ - *hash = sha384; -} - -/* - * SHA512 - */ -static int -sha512_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "sha512_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) { - (void) fprintf(stderr, "sha512_init: bad alloc\n"); - return 0; - } - SHA512_Init(hash->data); - return 1; -} - -static void -sha512_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha512_add", data, length); - } - SHA512_Update(hash->data, data, length); -} - -static unsigned -sha512_finish(pgp_hash_t *hash, uint8_t *out) -{ - SHA512_Final(out, hash->data); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha512_finish", out, SHA512_DIGEST_LENGTH); - } - free(hash->data); - hash->data = NULL; - return SHA512_DIGEST_LENGTH; -} - -static const pgp_hash_t sha512 = { - PGP_HASH_SHA512, - SHA512_DIGEST_LENGTH, - "SHA512", - sha512_init, - sha512_add, - sha512_finish, - NULL -}; - -void -pgp_hash_sha512(pgp_hash_t *hash) -{ - *hash = sha512; -} - -/* - * SHA224 - */ - -static int -sha224_init(pgp_hash_t *hash) -{ - if (hash->data) { - (void) fprintf(stderr, "sha224_init: hash data non-null\n"); - } - if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) { - (void) fprintf(stderr, "sha256_init: bad alloc\n"); - return 0; - } - SHA224_Init(hash->data); - return 1; -} - -static void -sha224_add(pgp_hash_t *hash, const uint8_t *data, unsigned length) -{ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha224_add", data, length); - } - SHA224_Update(hash->data, data, length); -} - -static unsigned -sha224_finish(pgp_hash_t *hash, uint8_t *out) -{ - SHA224_Final(out, hash->data); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH); - } - free(hash->data); - hash->data = NULL; - return SHA224_DIGEST_LENGTH; -} - -static const pgp_hash_t sha224 = { - PGP_HASH_SHA224, - SHA224_DIGEST_LENGTH, - "SHA224", - sha224_init, - sha224_add, - sha224_finish, - NULL -}; - -void -pgp_hash_sha224(pgp_hash_t *hash) -{ - *hash = sha224; -} - -unsigned -pgp_dsa_verify(const uint8_t *hash, size_t hash_length, - const pgp_dsa_sig_t *sig, - const pgp_dsa_pubkey_t *dsa) -{ - unsigned qlen; - DSA_SIG *osig; - DSA *odsa; - int ret; - - osig = DSA_SIG_new(); - DSA_SIG_set0(osig, - BN_dup(sig->r), - BN_dup(sig->s)); - - odsa = DSA_new(); - DSA_set0_pqg(odsa, - BN_dup(dsa->p), - BN_dup(dsa->q), - BN_dup(dsa->g)); - - DSA_set0_key(odsa, - BN_dup(dsa->y), - NULL); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "input hash", hash, hash_length); - (void) fprintf(stderr, "Q=%d\n", BN_num_bytes(dsa->q)); - } - if ((qlen = (unsigned)BN_num_bytes(dsa->q)) < hash_length) { - hash_length = qlen; - } - ret = DSA_do_verify(hash, (int)hash_length, osig, odsa); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "ret=%d\n", ret); - } - if (ret < 0) { - (void) fprintf(stderr, "pgp_dsa_verify: DSA verification\n"); - return 0; - } - - DSA_free(odsa); - - DSA_SIG_free(osig); - - return (unsigned)ret; -} - -/** - \ingroup Core_Crypto - \brief Recovers message digest from the signature - \param out Where to write decrypted data to - \param in Encrypted data - \param length Length of encrypted data - \param pubkey RSA public key - \return size of recovered message digest -*/ -int -pgp_rsa_public_decrypt(uint8_t *out, - const uint8_t *in, - size_t length, - const pgp_rsa_pubkey_t *pubkey) -{ - RSA *orsa; - int n; - - orsa = RSA_new(); - RSA_set0_key(orsa, - BN_dup(pubkey->n), - BN_dup(pubkey->e), - NULL); - - - n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); - - RSA_free(orsa); - - return n; -} - -/** - \ingroup Core_Crypto - \brief Signs data with RSA - \param out Where to write signature - \param in Data to sign - \param length Length of data - \param seckey RSA secret key - \param pubkey RSA public key - \return number of bytes decrypted -*/ -int -pgp_rsa_private_encrypt(uint8_t *out, - const uint8_t *in, - size_t length, - const pgp_rsa_seckey_t *seckey, - const pgp_rsa_pubkey_t *pubkey) -{ - RSA *orsa; - int n; - - orsa = RSA_new(); - - RSA_set0_key(orsa, - BN_dup(pubkey->n), - BN_dup(pubkey->e), - BN_dup(seckey->d)); - - /* p and q are round the other way in openssl */ - RSA_set0_factors(orsa, - /* q */ BN_dup(seckey->p), - /* p */ BN_dup(seckey->q)); - - - /* debug */ - if (RSA_check_key(orsa) != 1) { - (void) fprintf(stderr, "RSA_check_key is not set\n"); - return 0; - } - /* end debug */ - - n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); - - RSA_free(orsa); - - return n; -} - -/** -\ingroup Core_Crypto -\brief Decrypts RSA-encrypted data -\param out Where to write the plaintext -\param in Encrypted data -\param length Length of encrypted data -\param seckey RSA secret key -\param pubkey RSA public key -\return size of recovered plaintext -*/ -int -pgp_rsa_private_decrypt(uint8_t *out, - const uint8_t *in, - size_t length, - const pgp_rsa_seckey_t *seckey, - const pgp_rsa_pubkey_t *pubkey) -{ - RSA *keypair; - int n; - char errbuf[1024]; - - keypair = RSA_new(); - RSA_set0_key(keypair, - BN_dup(pubkey->n), - BN_dup(pubkey->e), - BN_dup(seckey->d)); - - RSA_set0_factors(keypair, - BN_dup(seckey->p), - BN_dup(seckey->q)); - - /* debug */ - if (RSA_check_key(keypair) != 1) { - (void) fprintf(stderr, "RSA_check_key is not set\n"); - return 0; - } - /* end debug */ - - n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING); - - if (pgp_get_debug_level(__FILE__)) { - printf("pgp_rsa_private_decrypt: n=%d\n",n); - } - - errbuf[0] = '\0'; - if (n == -1) { - unsigned long err = ERR_get_error(); - - ERR_error_string(err, &errbuf[0]); - (void) fprintf(stderr, "openssl error : %s\n", errbuf); - } - RSA_free(keypair); - - return n; -} - -/** - \ingroup Core_Crypto - \brief RSA-encrypts data - \param out Where to write the encrypted data - \param in Plaintext - \param length Size of plaintext - \param pubkey RSA Public Key -*/ -int -pgp_rsa_public_encrypt(uint8_t *out, - const uint8_t *in, - size_t length, - const pgp_rsa_pubkey_t *pubkey) -{ - RSA *orsa; - int n; - - /* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */ - - orsa = RSA_new(); - RSA_set0_key(orsa, - BN_dup(pubkey->n), - BN_dup(pubkey->e), - NULL); - - /* printf("len: %ld\n", length); */ - /* pgp_print_bn("n: ", orsa->n); */ - /* pgp_print_bn("e: ", orsa->e); */ - n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING); - - if (n == -1) { - BIO *fd_out; - - fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE); - ERR_print_errors(fd_out); - } - RSA_free(orsa); - - return n; -} - -/** - \ingroup Core_Crypto - \brief Finalise openssl - \note Would usually call pgp_finish() instead - \sa pgp_finish() -*/ -void -pgp_crypto_finish(void) -{ - // No cleanup since OpenSSL 1.1.0 - // CRYPTO_cleanup_all_ex_data(); -} - -/** - \ingroup Core_Hashes - \brief Get Hash name - \param hash Hash struct - \return Hash name -*/ -const char * -pgp_text_from_hash(pgp_hash_t *hash) -{ - return hash->name; -} - -/** - \ingroup HighLevel_KeyGenerate - \brief Generates an RSA keypair - \param numbits Modulus size - \param e Public Exponent - \param keydata Pointer to keydata struct to hold new key - \return 1 if key generated successfully; otherwise 0 - \note It is the caller's responsibility to call pgp_keydata_free(keydata) -*/ -unsigned -pgp_rsa_generate_keypair(pgp_key_t *keydata, - const int numbits, - const unsigned long e__, - const char *hashalg, - const char *cipher, - const uint8_t *passphrase, - const size_t pplen) -{ - pgp_seckey_t *seckey; - RSA *rsa; - BN_CTX *ctx; - pgp_output_t *output; - pgp_memory_t *mem; - int res; - const BIGNUM *_n = NULL; - const BIGNUM *_e = NULL; - const BIGNUM *_d = NULL; - const BIGNUM *_p = NULL; - const BIGNUM *_q = NULL; - - ctx = BN_CTX_new(); - pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY); - seckey = pgp_get_writable_seckey(keydata); - - /* generate the key pair */ - - BIGNUM *exp = BN_new(); - BN_set_word(exp, e__); - /* -#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - exp = BN_bin2bn((const unsigned char *)&e, sizeof(e), NULL); -#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - exp = BN_lebin2bn((const unsigned char *)&e, sizeof(e), NULL); -#else -#error Unsupported endian -#endif - if (!exp) - return 0; - */ - - rsa = RSA_new(); - res = RSA_generate_key_ex(rsa, numbits, exp, NULL); - - BN_free(exp); - - if (!res){ - RSA_free(rsa); - return 0; - }; - - /* populate pgp key from ssl key */ - - seckey->pubkey.version = PGP_V4; - seckey->pubkey.birthtime = time(NULL); - seckey->pubkey.days_valid = 0; - seckey->pubkey.alg = PGP_PKA_RSA; - - RSA_get0_key(rsa, &_n, &_e, &_d); - - seckey->pubkey.key.rsa.n = BN_dup(_n); - seckey->pubkey.key.rsa.e = BN_dup(_e); - - /* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */ - seckey->s2k_usage = PGP_S2KU_NONE; - /* seckey->s2k_specifier = PGP_S2KS_SALTED;*/ - /* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */ - if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) { - seckey->hash_alg = PGP_HASH_SHA1; - } - seckey->alg = pgp_str_to_cipher(cipher); - seckey->octetc = 0; - seckey->checksum = 0; - - RSA_get0_factors(rsa, &_p, &_q); - seckey->key.rsa.d = BN_dup(_d); - seckey->key.rsa.p = BN_dup(_p); - seckey->key.rsa.q = BN_dup(_q); - seckey->key.rsa.u = BN_mod_inverse(NULL, _p, _q, ctx); - if (seckey->key.rsa.u == NULL) { - RSA_free(rsa); - (void) fprintf(stderr, "seckey->key.rsa.u is NULL\n"); - return 0; - } - BN_CTX_free(ctx); - - RSA_free(rsa); - - pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg); - pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg); - - /* Generate checksum */ - - output = NULL; - mem = NULL; - - pgp_setup_memory_write(&output, &mem, 128); - - pgp_push_checksum_writer(output, seckey); - - switch (seckey->pubkey.alg) { - case PGP_PKA_DSA: - return pgp_write_mpi(output, seckey->key.dsa.x); - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (!pgp_write_mpi(output, seckey->key.rsa.d) || - !pgp_write_mpi(output, seckey->key.rsa.p) || - !pgp_write_mpi(output, seckey->key.rsa.q) || - !pgp_write_mpi(output, seckey->key.rsa.u)) { - return 0; - } - break; - case PGP_PKA_ELGAMAL: - return pgp_write_mpi(output, seckey->key.elgamal.x); - - default: - (void) fprintf(stderr, "Bad seckey->pubkey.alg\n"); - return 0; - } - - /* close rather than pop, since its the only one on the stack */ - pgp_writer_close(output); - pgp_teardown_memory_write(output, mem); - - /* should now have checksum in seckey struct */ - - /* test */ - if (pgp_get_debug_level(__FILE__)) { - test_seckey(seckey); - } - - return 1; -} - -/** - \ingroup HighLevel_KeyGenerate - \brief Creates a self-signed RSA keypair - \param numbits Modulus size - \param e Public Exponent - \param userid User ID - \return The new keypair or NULL - - \note It is the caller's responsibility to call pgp_keydata_free(keydata) - \sa pgp_rsa_generate_keypair() - \sa pgp_keydata_free() -*/ -#if 0 ////// -pgp_key_t * -pgp_rsa_new_selfsign_key(const int numbits, - const unsigned long e, - const uint8_t *userid, - const char *hashalg, - const char *cipher) -{ - pgp_key_t *keydata; - - keydata = pgp_keydata_new(); - if (!pgp_rsa_generate_keypair(keydata, numbits, e, hashalg, cipher, - (const uint8_t *) "", (const size_t) 0) || - !pgp_add_selfsigned_userid(keydata, NULL, userid, 0 /*never expire*/)) { - pgp_keydata_free(keydata); - return NULL; - } - return keydata; -} -#endif ////// - -pgp_dsa_sig_t * -pgp_dsa_sign(uint8_t *hashbuf, - unsigned hashsize, - const pgp_dsa_seckey_t *secdsa, - const pgp_dsa_pubkey_t *pubdsa) -{ - DSA_SIG *dsasig; - DSA *odsa; - pgp_dsa_sig_t *pgpdsasig; - const BIGNUM *pr = NULL; - const BIGNUM *ps = NULL; - - odsa = DSA_new(); - DSA_set0_pqg(odsa, - BN_dup(pubdsa->p), - BN_dup(pubdsa->q), - BN_dup(pubdsa->g)); - - DSA_set0_key(odsa, - BN_dup(pubdsa->y), - BN_dup(secdsa->x)); - - dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa); - - DSA_free(odsa); - - - DSA_SIG_get0(dsasig, &pr, &ps); - - pgpdsasig = calloc(1,sizeof(pgp_dsa_sig_t)); - if(pgpdsasig != NULL){ - pgpdsasig->r = BN_dup(pr); - pgpdsasig->s = BN_dup(ps); - } - - DSA_SIG_free(dsasig); - return pgpdsasig; -} - - -/* - * Decide the number of bits in the random componont k - * - * It should be in the same range as p for signing (which - * is deprecated), but can be much smaller for encrypting. - * - * Until I research it further, I just mimic gpg behaviour. - * It has a special mapping table, for values <= 5120, - * above that it uses 'arbitrary high number'. Following - * algorihm hovers 10-70 bits above gpg values. And for - * larger p, it uses gpg's algorihm. - * - * The point is - if k gets large, encryption will be - * really slow. It does not matter for decryption. - */ -static int -decide_k_bits(int p_bits) -{ - return (p_bits <= 5120) ? p_bits / 10 + 160 : (p_bits / 8 + 200) * 3 / 2; -} - -int -pgp_elgamal_public_encrypt(uint8_t *g_to_k, uint8_t *encm, - const uint8_t *in, - size_t size, - const pgp_elgamal_pubkey_t *pubkey) -{ - int ret = 0; - int k_bits; - BIGNUM *m; - BIGNUM *p; - BIGNUM *g; - BIGNUM *y; - BIGNUM *k; - BIGNUM *yk; - BIGNUM *c1; - BIGNUM *c2; - BN_CTX *tmp; - - m = BN_bin2bn(in, (int)size, NULL); - p = pubkey->p; - g = pubkey->g; - y = pubkey->y; - k = BN_new(); - yk = BN_new(); - c1 = BN_new(); - c2 = BN_new(); - tmp = BN_CTX_new(); - if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp) { - goto done; - } - /* - * generate k - */ - k_bits = decide_k_bits(BN_num_bits(p)); - if (!BN_rand(k, k_bits, 0, 0)) { - goto done; - } - /* - * c1 = g^k c2 = m * y^k - */ - if (!BN_mod_exp(c1, g, k, p, tmp)) { - goto done; - } - if (!BN_mod_exp(yk, y, k, p, tmp)) { - goto done; - } - if (!BN_mod_mul(c2, m, yk, p, tmp)) { - goto done; - } - /* result */ - BN_bn2bin(c1, g_to_k); - ret = BN_num_bytes(c1); /* c1 = g^k */ - BN_bn2bin(c2, encm); - ret += BN_num_bytes(c2); /* c2 = m * y^k */ -done: - if (tmp) { - BN_CTX_free(tmp); - } - if (c2) { - BN_clear_free(c2); - } - if (c1) { - BN_clear_free(c1); - } - if (yk) { - BN_clear_free(yk); - } - if (k) { - BN_clear_free(k); - } - if (g) { - BN_clear_free(g); - } - return ret; -} - -int -pgp_elgamal_private_decrypt(uint8_t *out, - const uint8_t *g_to_k, - const uint8_t *in, - size_t length, - const pgp_elgamal_seckey_t *seckey, - const pgp_elgamal_pubkey_t *pubkey) -{ - BIGNUM *bndiv; - BIGNUM *c1x; - BN_CTX *tmp; - BIGNUM *c1; - BIGNUM *c2; - BIGNUM *p; - BIGNUM *x; - BIGNUM *m; - int ret; - - ret = 0; - /* c1 and c2 are in g_to_k and in, respectively*/ - c1 = BN_bin2bn(g_to_k, (int)length, NULL); - c2 = BN_bin2bn(in, (int)length, NULL); - /* other bits */ - p = pubkey->p; - x = seckey->x; - c1x = BN_new(); - bndiv = BN_new(); - m = BN_new(); - tmp = BN_CTX_new(); - if (!c1 || !c2 || !p || !x || !c1x || !bndiv || !m || !tmp) { - goto done; - } - /* - * m = c2 / (c1^x) - */ - if (!BN_mod_exp(c1x, c1, x, p, tmp)) { - goto done; - } - if (!BN_mod_inverse(bndiv, c1x, p, tmp)) { - goto done; - } - if (!BN_mod_mul(m, c2, bndiv, p, tmp)) { - goto done; - } - /* result */ - ret = BN_bn2bin(m, out); -done: - if (tmp) { - BN_CTX_free(tmp); - } - if (m) { - BN_clear_free(m); - } - if (bndiv) { - BN_clear_free(bndiv); - } - if (c1x) { - BN_clear_free(c1x); - } - if (x) { - BN_clear_free(x); - } - if (p) { - BN_clear_free(p); - } - if (c1) { - BN_clear_free(c1); - } - if (c2) { - BN_clear_free(c2); - } - return ret; -} diff --git a/netpgp/packet-parse.c b/netpgp/packet-parse.c deleted file mode 100644 index dbf24506c66d0d1d14b01bfa58ec767b5a2ec73a..0000000000000000000000000000000000000000 --- a/netpgp/packet-parse.c +++ /dev/null @@ -1,3686 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * \brief Parser for OpenPGP packets - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/param.h> - -#ifdef HAVE_OPENSSL_CAST_H -#include <openssl/cast.h> -#endif - -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif - -#include "netpgp/packet.h" -#include "netpgp/packet-parse.h" -#include "netpgp/keyring.h" -#include "netpgp/errors.h" -#include "netpgp/packet-show.h" -#include "netpgp/create.h" -#include "netpgp/readerwriter.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/crypto.h" -#include "netpgp/netpgpdigest.h" - -#define ERRP(cbinfo, cont, err) do { \ - cont.u.error = err; \ - CALLBACK(PGP_PARSER_ERROR, cbinfo, &cont); \ - return 0; \ - /*NOTREACHED*/ \ -} while(/*CONSTCOND*/0) - -/** - * limread_data reads the specified amount of the subregion's data - * into a data_t structure - * - * \param data Empty structure which will be filled with data - * \param len Number of octets to read - * \param subregion - * \param stream How to parse - * - * \return 1 on success, 0 on failure - */ -static int -limread_data(pgp_data_t *data, unsigned len, - pgp_region_t *subregion, pgp_stream_t *stream) -{ - data->len = len; - - if (subregion->length - subregion->readc < len) { - (void) fprintf(stderr, "limread_data: bad length\n"); - return 0; - } - - data->contents = calloc(1, data->len); - if (!data->contents) { - return 0; - } - - return pgp_limited_read(stream, data->contents, data->len, subregion, - &stream->errors, &stream->readinfo, &stream->cbinfo); -} - -/** - * read_data reads the remainder of the subregion's data - * into a data_t structure - * - * \param data - * \param subregion - * \param stream - * - * \return 1 on success, 0 on failure - */ -static int -read_data(pgp_data_t *data, pgp_region_t *region, pgp_stream_t *stream) -{ - int cc; - - cc = region->length - region->readc; - return (cc >= 0) ? limread_data(data, (unsigned)cc, region, stream) : 0; -} - -/** - * Reads the remainder of the subregion as a string. - * It is the user's responsibility to free the memory allocated here. - */ - -static int -read_unsig_str(uint8_t **str, pgp_region_t *subregion, - pgp_stream_t *stream) -{ - size_t len; - - len = subregion->length - subregion->readc; - if ((*str = calloc(1, len + 1)) == NULL) { - return 0; - } - if (len && - !pgp_limited_read(stream, *str, len, subregion, &stream->errors, - &stream->readinfo, &stream->cbinfo)) { - return 0; - } - (*str)[len] = '\0'; - return 1; -} - -static int -read_string(char **str, pgp_region_t *subregion, pgp_stream_t *stream) -{ - return read_unsig_str((uint8_t **) str, subregion, stream); -} - -void -pgp_init_subregion(pgp_region_t *subregion, pgp_region_t *region) -{ - (void) memset(subregion, 0x0, sizeof(*subregion)); - subregion->parent = region; -} - -/* - * XXX: replace pgp_ptag_t with something more appropriate for limiting reads - */ - -/* data from partial blocks is queued up in virtual block in stream */ -static int -read_partial_data(pgp_stream_t *stream, - pgp_reader_t *readinfo, - void *dest, size_t length) -{ - unsigned n; - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "fd_reader: coalesced data, off %d\n", - readinfo->virtualoff); - } - n = MIN(readinfo->virtualc - readinfo->virtualoff, (unsigned)length); - (void) memcpy(dest, &readinfo->virtualpkt[readinfo->virtualoff], n); - readinfo->virtualoff += n; - if (readinfo->virtualoff == readinfo->virtualc) { - free(readinfo->virtualpkt); - readinfo->virtualpkt = NULL; - readinfo->virtualc = readinfo->virtualoff = 0; - } - return (int)n; -} - - -/** - * low-level function to read data from reader function - * - * Use this function, rather than calling the reader directly. - * - * If the accumulate flag is set in *stream, the function - * adds the read data to the accumulated data, and updates - * the accumulated length. This is useful if, for example, - * the application wants access to the raw data as well as the - * parsed data. - * - * This function will also try to read the entire amount asked for, but not - * if it is over INT_MAX. Obviously many callers will know that they - * never ask for that much and so can avoid the extra complexity of - * dealing with return codes and filled-in lengths. - * - * \param *dest - * \param *plength - * \param flags - * \param *stream - * - * \return PGP_R_OK - * \return PGP_R_PARTIAL_READ - * \return PGP_R_EOF - * \return PGP_R_EARLY_EOF - * - * \sa #pgp_reader_ret_t for details of return codes - */ - -static int -sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - size_t n; - - /* reading more than this would look like an error */ - if (length > INT_MAX) - length = INT_MAX; - - for (n = 0; n < length;) { - int r; - - if (!readinfo->coalescing && readinfo->virtualc && readinfo->virtualoff < readinfo->virtualc) { - r = read_partial_data(stream, readinfo, (char*) dest + n, length - n); - }else{ - r = readinfo->reader(stream, (char *) dest + n, - length - n, errors, - readinfo, cbinfo); - } - if (r > (int)(length - n)) { - (void) fprintf(stderr, "sub_base_read: bad read\n"); - return 0; - } - if (r < 0) { - return r; - } - if (r == 0) { - break; - } - n += (unsigned)r; - } - - if (n == 0) { - return 0; - } - if (readinfo->accumulate) { - if (readinfo->asize < readinfo->alength) { - (void) fprintf(stderr, "sub_base_read: bad size\n"); - return 0; - } - if (readinfo->alength + n > readinfo->asize) { - uint8_t *temp; - - readinfo->asize = (readinfo->asize * 2) + (unsigned)n; - temp = realloc(readinfo->accumulated, readinfo->asize); - if (temp == NULL) { - (void) fprintf(stderr, - "sub_base_read: bad alloc\n"); - return 0; - } - readinfo->accumulated = temp; - } - if (readinfo->asize < readinfo->alength + n) { - (void) fprintf(stderr, "sub_base_read: bad realloc\n"); - return 0; - } - (void) memcpy(readinfo->accumulated + readinfo->alength, dest, - n); - } - /* we track length anyway, because it is used for packet offsets */ - readinfo->alength += (unsigned)n; - /* and also the position */ - readinfo->position += (unsigned)n; - - return (int)n; -} - -int -pgp_stacked_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - return sub_base_read(stream, dest, length, errors, readinfo->next, cbinfo); -} - -/* This will do a full read so long as length < MAX_INT */ -static int -base_read(uint8_t *dest, size_t length, pgp_stream_t *stream) -{ - return sub_base_read(stream, dest, length, &stream->errors, &stream->readinfo, - &stream->cbinfo); -} - -/* - * Read a full size_t's worth. If the return is < than length, then - * *last_read tells you why - < 0 for an error, == 0 for EOF - */ - -static size_t -full_read(pgp_stream_t *stream, uint8_t *dest, - size_t length, - int *last_read, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - size_t t; - int r = 0; /* preset in case some loon calls with length - * == 0 */ - - for (t = 0; t < length;) { - r = sub_base_read(stream, dest + t, length - t, errors, readinfo, - cbinfo); - if (r <= 0) { - *last_read = r; - return t; - } - t += (size_t)r; - } - - *last_read = r; - - return t; -} - - - -/** Read a scalar value of selected length from reader. - * - * Read an unsigned scalar value from reader in Big Endian representation. - * - * This function does not know or care about packet boundaries. It - * also assumes that an EOF is an error. - * - * \param *result The scalar value is stored here - * \param *reader Our reader - * \param length How many bytes to read - * \return 1 on success, 0 on failure - */ -static unsigned -_read_scalar(unsigned *result, unsigned length, - pgp_stream_t *stream) -{ - unsigned t = 0; - - if (length > sizeof(*result)) { - (void) fprintf(stderr, "_read_scalar: bad length\n"); - return 0; - } - - while (length--) { - uint8_t c; - int r; - - r = base_read(&c, 1, stream); - if (r != 1) - return 0; - t = (t << 8) + c; - } - - *result = t; - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Read bytes from a region within the packet. - * - * Read length bytes into the buffer pointed to by *dest. - * Make sure we do not read over the packet boundary. - * Updates the Packet Tag's pgp_ptag_t::readc. - * - * If length would make us read over the packet boundary, or if - * reading fails, we call the callback with an error. - * - * Note that if the region is indeterminate, this can return a short - * read - check region->last_read for the length. EOF is indicated by - * a success return and region->last_read == 0 in this case (for a - * region of known length, EOF is an error). - * - * This function makes sure to respect packet boundaries. - * - * \param dest The destination buffer - * \param length How many bytes to read - * \param region Pointer to packet region - * \param errors Error stack - * \param readinfo Reader info - * \param cbinfo Callback info - * \return 1 on success, 0 on error - */ -unsigned -pgp_limited_read(pgp_stream_t *stream, uint8_t *dest, - size_t length, - pgp_region_t *region, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - size_t r; - int lr; - - if (!region->indeterminate && - region->readc + length > region->length) { - PGP_ERROR_1(errors, PGP_E_P_NOT_ENOUGH_DATA, "%s", - "Not enough data"); - return 0; - } - r = full_read(stream, dest, length, &lr, errors, readinfo, cbinfo); - if (lr < 0) { - PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed"); - return 0; - } - if (!region->indeterminate && r != length) { - PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed"); - return 0; - } - region->last_read = (unsigned)r; - do { - region->readc += (unsigned)r; - if (region->parent && region->length > region->parent->length) { - (void) fprintf(stderr, - "ops_limited_read: bad length\n"); - return 0; - } - } while ((region = region->parent) != NULL); - return 1; -} - -/** - \ingroup Core_ReadPackets - \brief Call pgp_limited_read on next in stack -*/ -unsigned -pgp_stacked_limited_read(pgp_stream_t *stream, uint8_t *dest, unsigned length, - pgp_region_t *region, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - return pgp_limited_read(stream, dest, length, region, errors, - readinfo->next, cbinfo); -} - -static unsigned -limread(uint8_t *dest, unsigned length, - pgp_region_t *region, pgp_stream_t *info) -{ - return pgp_limited_read(info, dest, length, region, &info->errors, - &info->readinfo, &info->cbinfo); -} - -#if 0 -static unsigned -exact_limread(uint8_t *dest, unsigned len, - pgp_region_t *region, - pgp_stream_t *stream) -{ - unsigned ret; - - stream->exact_read = 1; - ret = limread(dest, len, region, stream); - stream->exact_read = 0; - return ret; -} -#endif - -/** Skip over length bytes of this packet. - * - * Calls limread() to skip over some data. - * - * This function makes sure to respect packet boundaries. - * - * \param length How many bytes to skip - * \param *region Pointer to packet region - * \param *stream How to parse - * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()). - */ -static int -limskip(unsigned length, pgp_region_t *region, pgp_stream_t *stream) -{ - uint8_t buf[NETPGP_BUFSIZ]; - - while (length > 0) { - unsigned n = length % NETPGP_BUFSIZ; - - if (!limread(buf, n, region, stream)) { - return 0; - } - length -= n; - } - return 1; -} - -/** Read a scalar. - * - * Read a big-endian scalar of length bytes, respecting packet - * boundaries (by calling limread() to read the raw data). - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The scalar value is stored here - * \param length How many bytes make up this scalar (at most 4) - * \param *region Pointer to current packet region - * \param *stream How to parse - * \param *cb The callback - * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()). - * - * \see RFC4880 3.1 - */ -static int -limread_scalar(unsigned *dest, - unsigned len, - pgp_region_t *region, - pgp_stream_t *stream) -{ - uint8_t c[4] = ""; - unsigned t; - unsigned n; - - if (len > 4) { - (void) fprintf(stderr, "limread_scalar: bad length\n"); - return 0; - } - /*LINTED*/ - if (/*CONSTCOND*/sizeof(*dest) < 4) { - (void) fprintf(stderr, "limread_scalar: bad dest\n"); - return 0; - } - if (!limread(c, len, region, stream)) { - return 0; - } - for (t = 0, n = 0; n < len; ++n) { - t = (t << 8) + c[n]; - } - *dest = t; - return 1; -} - -/** Read a scalar. - * - * Read a big-endian scalar of length bytes, respecting packet - * boundaries (by calling limread() to read the raw data). - * - * The value read is stored in a size_t, which is a different size - * from an unsigned on some platforms. - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The scalar value is stored here - * \param length How many bytes make up this scalar (at most 4) - * \param *region Pointer to current packet region - * \param *stream How to parse - * \param *cb The callback - * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()). - * - * \see RFC4880 3.1 - */ -static int -limread_size_t(size_t *dest, - unsigned length, - pgp_region_t *region, - pgp_stream_t *stream) -{ - unsigned tmp; - - /* - * Note that because the scalar is at most 4 bytes, we don't care if - * size_t is bigger than usigned - */ - if (!limread_scalar(&tmp, length, region, stream)) - return 0; - - *dest = tmp; - return 1; -} - -/** Read a timestamp. - * - * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970). They are stored in an unsigned scalar - * of 4 bytes. - * - * This function reads the timestamp using limread_scalar(). - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The timestamp is stored here - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return see limread_scalar() - * - * \see RFC4880 3.5 - */ -static int -limited_read_time(time_t *dest, pgp_region_t *region, - pgp_stream_t *stream) -{ - uint8_t c; - time_t mytime = 0; - int i; - - /* - * Cannot assume that time_t is 4 octets long - - * SunOS 5.10 and NetBSD both have 64-bit time_ts. - */ - if (/* CONSTCOND */sizeof(time_t) == 4) { - return limread_scalar((unsigned *)(void *)dest, 4, region, stream); - } - for (i = 0; i < 4; i++) { - if (!limread(&c, 1, region, stream)) { - return 0; - } - mytime = (mytime << 8) + c; - } - *dest = mytime; - return 1; -} - -/** - * \ingroup Core_MPI - * Read a multiprecision integer. - * - * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts. First there is a 2 byte scalar - * indicating the length of the following MPI in Bits. Then follow the bits that make up the actual number, most - * significant bits first (Big Endian). The most significant bit in the MPI is supposed to be 1 (unless the MPI is - * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted). - * - * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are - * supposed to be cleared - I guess. XXX - does anything actually say so? - * - * This function makes sure to respect packet boundaries. - * - * \param **pgn return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed - * by the caller XXX right ben? - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX - * see comment below - the callback is called with a PGP_PARSER_ERROR in case of an error) - * - * \see RFC4880 3.2 - */ -static int -limread_mpi(BIGNUM **pbn, pgp_region_t *region, pgp_stream_t *stream) -{ - uint8_t buf[NETPGP_BUFSIZ] = ""; - /* an MPI has a 2 byte length part. - * Length is given in bits, so the - * largest we should ever need for - * the buffer is NETPGP_BUFSIZ bytes. */ - unsigned length; - unsigned nonzero; - unsigned ret; - - //stream->reading_mpi_len = 1; - ret = (unsigned)limread_scalar(&length, 2, region, stream); - - //stream->reading_mpi_len = 0; - if (!ret) - return 0; - - nonzero = length & 7; /* there should be this many zero bits in the - * MS byte */ - if (!nonzero) - nonzero = 8; - length = (length + 7) / 8; - - if (length == 0) { - /* if we try to read a length of 0, then fail */ - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "limread_mpi: 0 length\n"); - } - return 0; - } - if (length > NETPGP_BUFSIZ) { - (void) fprintf(stderr, "limread_mpi: bad length\n"); - return 0; - } - if (!limread(buf, length, region, stream)) { - return 0; - } - if (((unsigned)buf[0] >> nonzero) != 0 || - !((unsigned)buf[0] & (1U << (nonzero - 1U)))) { - PGP_ERROR_1(&stream->errors, PGP_E_P_MPI_FORMAT_ERROR, - "%s", "MPI Format error"); - /* XXX: Ben, one part of - * this constraint does - * not apply to - * encrypted MPIs the - * draft says. -- peter */ - return 0; - } - *pbn = BN_bin2bn(buf, (int)length, NULL); - return 1; -} - -static unsigned read_new_length(unsigned *, pgp_stream_t *); - -/* allocate space, read, and stash data away in a virtual pkt */ -static void -streamread(pgp_stream_t *stream, unsigned c) -{ - int cc; - pgp_reader_t *readinfo = &stream->readinfo; - - readinfo->virtualpkt = realloc(readinfo->virtualpkt, readinfo->virtualc + c); - cc = readinfo->reader(stream, &readinfo->virtualpkt[readinfo->virtualc], - c, &stream->errors, readinfo, &stream->cbinfo); - readinfo->virtualc += cc; -} - -/* coalesce all the partial blocks together */ -static int -coalesce_blocks(pgp_stream_t *stream, unsigned length) -{ - unsigned c; - unsigned r; - - pgp_reader_t *readinfo = &stream->readinfo; - readinfo->coalescing = 1; - - /* already read a partial block length - prime the array */ - streamread(stream, length); - while ((r = read_new_length(&c, stream)) && readinfo->partial_read) { - /* length we read is partial - add to end of array */ - streamread(stream, c); - } - /* not partial - add the last extent to the end of the array */ - if(r > 0) streamread(stream, c); - readinfo->coalescing = 0; - return 1; -} - -/** Read some data with a New-Format length from reader. - * - * \sa Internet-Draft RFC4880.txt Section 4.2.2 - * - * \param *length Where the decoded length will be put - * \param *stream How to parse - * \return 1 if OK, else 0 - * - */ - -static unsigned -read_new_length(unsigned *length, pgp_stream_t *stream) -{ - uint8_t c; - pgp_reader_t *readinfo = &stream->readinfo; - - readinfo->partial_read = 0; - if (base_read(&c, 1, stream) != 1) { - return 0; - } - if (c < 192) { - /* 1. One-octet packet */ - *length = c; - return 1; - } - if (c < 224) { - /* 2. Two-octet packet */ - unsigned t = (c - 192) << 8; - - if (base_read(&c, 1, stream) != 1) { - return 0; - } - *length = t + c + 192; - return 1; - } - if (c < 255) { - /* 3. Partial Body Length */ - readinfo->partial_read = 1; - *length = 1 << (c & 0x1f); - if (!readinfo->coalescing) { - /* we have been called from coalesce_blocks - - * just return with the partial length */ - coalesce_blocks(stream, *length); - *length = readinfo->virtualc; - } - return 1; - } - /* 4. Five-Octet packet */ - return _read_scalar(length, 4, stream); -} - -/** Read the length information for a new format Packet Tag. - * - * New style Packet Tags encode the length in one to five octets. This function reads the right amount of bytes and - * decodes it to the proper length information. - * - * This function makes sure to respect packet boundaries. - * - * \param *length return the length here - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX - * see comment below) - * - * \see RFC4880 4.2.2 - * \see pgp_ptag_t - */ -static int -limited_read_new_length(unsigned *length, pgp_region_t *region, - pgp_stream_t *stream) -{ - uint8_t c = 0x0; - pgp_reader_t *readinfo = &stream->readinfo; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - if (c < 192) { - *length = c; - return 1; - } - if (c < 224) { - unsigned t = (c - 192) << 8; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - *length = t + c + 192; - return 1; - } - if (c < 255) { - readinfo->partial_read = 1; - *length = 1 << (c & 0x1f); - if (!readinfo->coalescing) { - /* we have been called from coalesce_blocks - - * just return with the partial length */ - coalesce_blocks(stream, *length); - *length = readinfo->virtualc; - } - return 1; - } - return limread_scalar(length, 4, region, stream); -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void -pgp_data_free(pgp_data_t *data) -{ - free(data->contents); - data->contents = NULL; - data->len = 0; -} - -void -pgp_data_dup(pgp_data_t *dst, const pgp_data_t *src) -{ - dst->contents = calloc(1, src->len); - memcpy(dst->contents, src->contents, src->len); - dst->len = src->len; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void -string_free(char **str) -{ - free(*str); - *str = NULL; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/* ! Free packet memory, set pointer to NULL */ -void -pgp_subpacket_free(pgp_subpacket_t *packet) -{ - free(packet->raw); - packet->raw = NULL; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void -headers_free(pgp_headers_t *headers) -{ - unsigned n; - - for (n = 0; n < headers->headerc; ++n) { - free(headers->headers[n].key); - free(headers->headers[n].value); - } - free(headers->headers); - headers->headers = NULL; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void -cleartext_trailer_free(struct pgp_hash_t **trailer) -{ - free(*trailer); - *trailer = NULL; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void -cmd_get_passphrase_free(pgp_seckey_passphrase_t *skp) -{ - if (skp->passphrase && *skp->passphrase) { - free(*skp->passphrase); - *skp->passphrase = NULL; - } -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void -free_BN(BIGNUM **pp) -{ - BN_free(*pp); - *pp = NULL; -} - -static void -dup_BN(BIGNUM **dst, const BIGNUM *src) -{ - *dst = BN_dup(src); -} - -void -copy_sig_info(pgp_sig_info_t *dst, const pgp_sig_info_t *src) -{ - (void) memcpy(dst, src, sizeof(*src)); - - if ((dst->v4_hashed = calloc(1, src->v4_hashlen)) == NULL) { - (void) fprintf(stderr, "copy_sig_info: bad alloc\n"); - } else { - (void) memcpy(dst->v4_hashed, src->v4_hashed, src->v4_hashlen); - } - - switch (src->key_alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_SIGN_ONLY: - dup_BN(&dst->sig.rsa.sig, src->sig.rsa.sig); - break; - - case PGP_PKA_DSA: - dup_BN(&dst->sig.dsa.r, src->sig.dsa.r); - dup_BN(&dst->sig.dsa.s, src->sig.dsa.s); - break; - - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - dup_BN(&dst->sig.elgamal.r, src->sig.elgamal.r); - dup_BN(&dst->sig.elgamal.s, src->sig.elgamal.s); - break; - - case PGP_PKA_PRIVATE00: - case PGP_PKA_PRIVATE01: - case PGP_PKA_PRIVATE02: - case PGP_PKA_PRIVATE03: - case PGP_PKA_PRIVATE04: - case PGP_PKA_PRIVATE05: - case PGP_PKA_PRIVATE06: - case PGP_PKA_PRIVATE07: - case PGP_PKA_PRIVATE08: - case PGP_PKA_PRIVATE09: - case PGP_PKA_PRIVATE10: - pgp_data_dup(&dst->sig.unknown, &src->sig.unknown); - break; - - default: - (void) fprintf(stderr, "sig_dup: bad sig type\n"); - } -} -/** - * \ingroup Core_Create - * \brief Free the memory used when parsing a signature - * \param sig - */ -void -pgp_free_sig_info(pgp_sig_info_t *info) -{ - free(info->v4_hashed); - - switch (info->key_alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_SIGN_ONLY: - free_BN(&info->sig.rsa.sig); - break; - - case PGP_PKA_DSA: - free_BN(&info->sig.dsa.r); - free_BN(&info->sig.dsa.s); - break; - - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - free_BN(&info->sig.elgamal.r); - free_BN(&info->sig.elgamal.s); - break; - - case PGP_PKA_PRIVATE00: - case PGP_PKA_PRIVATE01: - case PGP_PKA_PRIVATE02: - case PGP_PKA_PRIVATE03: - case PGP_PKA_PRIVATE04: - case PGP_PKA_PRIVATE05: - case PGP_PKA_PRIVATE06: - case PGP_PKA_PRIVATE07: - case PGP_PKA_PRIVATE08: - case PGP_PKA_PRIVATE09: - case PGP_PKA_PRIVATE10: - pgp_data_free(&info->sig.unknown); - break; - - default: - (void) fprintf(stderr, "info-free: bad info-type\n"); - } - memset(info, 0, sizeof(pgp_sig_info_t)); -} - -static void -sig_free(pgp_sig_t *sig) -{ - pgp_free_sig_info(&sig->info); -} - - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/* ! Free any memory allocated when parsing the packet content */ -void -pgp_parser_content_free(pgp_packet_t *c) -{ - switch (c->tag) { - case PGP_PARSER_PTAG: - case PGP_PTAG_CT_COMPRESSED: - case PGP_PTAG_SS_CREATION_TIME: - case PGP_PTAG_SS_EXPIRATION_TIME: - case PGP_PTAG_SS_KEY_EXPIRY: - case PGP_PTAG_SS_TRUST: - case PGP_PTAG_SS_ISSUER_KEY_ID: - case PGP_PTAG_CT_1_PASS_SIG: - case PGP_PTAG_SS_PRIMARY_USER_ID: - case PGP_PTAG_SS_REVOCABLE: - case PGP_PTAG_SS_REVOCATION_KEY: - case PGP_PTAG_CT_LITDATA_HEADER: - case PGP_PTAG_CT_LITDATA_BODY: - case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY: - case PGP_PTAG_CT_UNARMOURED_TEXT: - case PGP_PTAG_CT_ARMOUR_TRAILER: - case PGP_PTAG_CT_SIGNATURE_HEADER: - case PGP_PTAG_CT_SE_DATA_HEADER: - case PGP_PTAG_CT_SE_IP_DATA_HEADER: - case PGP_PTAG_CT_SE_IP_DATA_BODY: - case PGP_PTAG_CT_MDC: - case PGP_GET_SECKEY: - break; - - case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - headers_free(&c->u.cleartext_head); - break; - - case PGP_PTAG_CT_ARMOUR_HEADER: - headers_free(&c->u.armour_header.headers); - break; - - case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - cleartext_trailer_free(&c->u.cleartext_trailer); - break; - - case PGP_PTAG_CT_TRUST: - pgp_data_free(&c->u.trust); - break; - - case PGP_PTAG_CT_SIGNATURE: - case PGP_PTAG_CT_SIGNATURE_FOOTER: - sig_free(&c->u.sig); - break; - - case PGP_PTAG_CT_PUBLIC_KEY: - case PGP_PTAG_CT_PUBLIC_SUBKEY: - pgp_pubkey_free(&c->u.pubkey); - break; - - case PGP_PTAG_CT_USER_ID: - pgp_userid_free(&c->u.userid); - break; - - case PGP_PTAG_SS_SIGNERS_USER_ID: - pgp_userid_free(&c->u.ss_signer); - break; - - case PGP_PTAG_CT_USER_ATTR: - pgp_data_free(&c->u.userattr); - break; - - case PGP_PTAG_SS_PREFERRED_SKA: - pgp_data_free(&c->u.ss_skapref); - break; - - case PGP_PTAG_SS_PREFERRED_HASH: - pgp_data_free(&c->u.ss_hashpref); - break; - - case PGP_PTAG_SS_PREF_COMPRESS: - pgp_data_free(&c->u.ss_zpref); - break; - - case PGP_PTAG_SS_KEY_FLAGS: - pgp_data_free(&c->u.ss_key_flags); - break; - - case PGP_PTAG_SS_KEYSERV_PREFS: - pgp_data_free(&c->u.ss_key_server_prefs); - break; - - case PGP_PTAG_SS_FEATURES: - pgp_data_free(&c->u.ss_features); - break; - - case PGP_PTAG_SS_NOTATION_DATA: - pgp_data_free(&c->u.ss_notation.name); - pgp_data_free(&c->u.ss_notation.value); - break; - - case PGP_PTAG_SS_REGEXP: - string_free(&c->u.ss_regexp); - break; - - case PGP_PTAG_SS_POLICY_URI: - string_free(&c->u.ss_policy); - break; - - case PGP_PTAG_SS_PREF_KEYSERV: - string_free(&c->u.ss_keyserv); - break; - - case PGP_PTAG_SS_USERDEFINED00: - case PGP_PTAG_SS_USERDEFINED01: - case PGP_PTAG_SS_USERDEFINED02: - case PGP_PTAG_SS_USERDEFINED03: - case PGP_PTAG_SS_USERDEFINED04: - case PGP_PTAG_SS_USERDEFINED05: - case PGP_PTAG_SS_USERDEFINED06: - case PGP_PTAG_SS_USERDEFINED07: - case PGP_PTAG_SS_USERDEFINED08: - case PGP_PTAG_SS_USERDEFINED09: - case PGP_PTAG_SS_USERDEFINED10: - pgp_data_free(&c->u.ss_userdef); - break; - - case PGP_PTAG_SS_RESERVED: - pgp_data_free(&c->u.ss_unknown); - break; - - case PGP_PTAG_SS_REVOCATION_REASON: - string_free(&c->u.ss_revocation.reason); - break; - - case PGP_PTAG_SS_EMBEDDED_SIGNATURE: - pgp_data_free(&c->u.ss_embedded_sig); - break; - - case PGP_PARSER_PACKET_END: - pgp_subpacket_free(&c->u.packet); - break; - - case PGP_PARSER_ERROR: - case PGP_PARSER_ERRCODE: - break; - - case PGP_PTAG_CT_SECRET_KEY: - case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY: - pgp_seckey_free(&c->u.seckey); - break; - - case PGP_PTAG_CT_PK_SESSION_KEY: - case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - pgp_pk_sesskey_free(&c->u.pk_sesskey); - break; - - case PGP_GET_PASSPHRASE: - cmd_get_passphrase_free(&c->u.skey_passphrase); - break; - - default: - fprintf(stderr, "Can't free %d (0x%x)\n", c->tag, c->tag); - } -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void -pgp_pk_sesskey_free(pgp_pk_sesskey_t *sk) -{ - switch (sk->alg) { - case PGP_PKA_RSA: - free_BN(&sk->params.rsa.encrypted_m); - break; - - case PGP_PKA_ELGAMAL: - free_BN(&sk->params.elgamal.g_to_k); - free_BN(&sk->params.elgamal.encrypted_m); - break; - - default: - (void) fprintf(stderr, "pgp_pk_sesskey_free: bad alg\n"); - break; - } -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/* ! Free the memory used when parsing a public key */ -void -pgp_pubkey_free(pgp_pubkey_t *p) -{ - switch (p->alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - free_BN(&p->key.rsa.n); - free_BN(&p->key.rsa.e); - break; - - case PGP_PKA_DSA: - free_BN(&p->key.dsa.p); - free_BN(&p->key.dsa.q); - free_BN(&p->key.dsa.g); - free_BN(&p->key.dsa.y); - break; - - case PGP_PKA_ELGAMAL: - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - free_BN(&p->key.elgamal.p); - free_BN(&p->key.elgamal.g); - free_BN(&p->key.elgamal.y); - break; - - case PGP_PKA_NOTHING: - /* nothing to free */ - break; - - default: - (void) fprintf(stderr, "pgp_pubkey_free: bad alg\n"); - } - memset(p, 0, sizeof(*p)); -} - -int -pgp_pubkey_dup(pgp_pubkey_t *dst, pgp_pubkey_t *src) -{ - memcpy(dst, src, sizeof(*src)); - - switch (src->alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - dup_BN(&dst->key.rsa.n, src->key.rsa.n); - dup_BN(&dst->key.rsa.e, src->key.rsa.e); - break; - - case PGP_PKA_DSA: - dup_BN(&dst->key.dsa.p, src->key.dsa.p); - dup_BN(&dst->key.dsa.q, src->key.dsa.q); - dup_BN(&dst->key.dsa.g, src->key.dsa.g); - dup_BN(&dst->key.dsa.y, src->key.dsa.y); - break; - - case PGP_PKA_ELGAMAL: - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - dup_BN(&dst->key.elgamal.p, src->key.elgamal.p); - dup_BN(&dst->key.elgamal.g, src->key.elgamal.g); - dup_BN(&dst->key.elgamal.y, src->key.elgamal.y); - break; - - case PGP_PKA_NOTHING: - /* nothing to dup */ - break; - - default: - (void) fprintf(stderr, "pgp_pubkey_dup: bad alg\n"); - return 0; - } - - /*TODO alloc error handling */ - return 1; -} -/** - \ingroup Core_ReadPackets -*/ -static int -parse_pubkey_data(pgp_pubkey_t *key, pgp_region_t *region, - pgp_stream_t *stream) -{ - uint8_t c = 0x0; - - if (region->readc != 0) { - /* We should not have read anything so far */ - (void) fprintf(stderr, "parse_pubkey_data: bad length\n"); - return 0; - } - if (!limread(&c, 1, region, stream)) { - return 0; - } - key->version = (pgp_version_t)c; - switch (key->version) { - case PGP_V2: - case PGP_V3: - case PGP_V4: - break; - default: - PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN, - "Bad public key version (0x%02x)", key->version); - return 0; - } - if (!limited_read_time(&key->birthtime, region, stream)) { - return 0; - } - - key->days_valid = 0; - if ((key->version == 2 || key->version == 3) && - !limread_scalar(&key->days_valid, 2, region, stream)) { - return 0; - } - - if (!limread(&c, 1, region, stream)) { - return 0; - } - key->alg = c; - - switch (key->alg) { - case PGP_PKA_DSA: - if (!limread_mpi(&key->key.dsa.p, region, stream) || - !limread_mpi(&key->key.dsa.q, region, stream) || - !limread_mpi(&key->key.dsa.g, region, stream) || - !limread_mpi(&key->key.dsa.y, region, stream)) { - return 0; - } - break; - - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (!limread_mpi(&key->key.rsa.n, region, stream) || - !limread_mpi(&key->key.rsa.e, region, stream)) { - return 0; - } - break; - - case PGP_PKA_ELGAMAL: - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if (!limread_mpi(&key->key.elgamal.p, region, stream) || - !limread_mpi(&key->key.elgamal.g, region, stream) || - !limread_mpi(&key->key.elgamal.y, region, stream)) { - return 0; - } - break; - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG, - "Unsupported Public Key algorithm (%s)", - pgp_show_pka(key->alg)); - return 0; - } - - return 1; -} - - -/** - * \ingroup Core_ReadPackets - * \brief Parse a public key packet. - * - * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys. - * - * Once the key has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the current Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.5.2 - */ -static int -parse_pubkey(pgp_content_enum tag, pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_packet_t pkt; - - if (!parse_pubkey_data(&pkt.u.pubkey, region, stream)) { - (void) fprintf(stderr, "parse_pubkey: parse_pubkey_data failed\n"); - return 0; - } - - /* XXX: this test should be done for all packets, surely? */ - if (region->readc != region->length) { - PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", region->length - region->readc); - return 0; - } - CALLBACK(tag, &stream->cbinfo, &pkt); - - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse one user attribute packet. - * - * User attribute packets contain one or more attribute subpackets. - * For now, handle the whole packet as raw data. - */ - -static int -parse_userattr(pgp_region_t *region, pgp_stream_t *stream) -{ - - pgp_packet_t pkt; - - /* - * xxx- treat as raw data for now. Could break down further into - * attribute sub-packets later - rachel - */ - if (region->readc != 0) { - /* We should not have read anything so far */ - (void) fprintf(stderr, "parse_userattr: bad length\n"); - return 0; - } - if (!read_data(&pkt.u.userattr, region, stream)) { - return 0; - } - CALLBACK(PGP_PTAG_CT_USER_ATTR, &stream->cbinfo, &pkt); - return 1; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/* ! Free the memory used when parsing this packet type */ -void -pgp_userid_free(uint8_t **id) -{ - free(*id); - *id = NULL; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse a user id. - * - * This function parses an user id packet, which is basically just a char array the size of the packet. - * - * The char array is to be treated as an UTF-8 string. - * - * The userid gets null terminated by this function. Freeing it is the responsibility of the caller. - * - * Once the userid has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.11 - */ -static int -parse_userid(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - - if (region->readc != 0) { - /* We should not have read anything so far */ - (void) fprintf(stderr, "parse_userid: bad length\n"); - return 0; - } - - if ((pkt.u.userid = calloc(1, region->length + 1)) == NULL) { - (void) fprintf(stderr, "parse_userid: bad alloc\n"); - return 0; - } - - if (region->length && - !limread(pkt.u.userid, region->length, region, - stream)) { - return 0; - } - pkt.u.userid[region->length] = 0x0; - CALLBACK(PGP_PTAG_CT_USER_ID, &stream->cbinfo, &pkt); - return 1; -} - -static pgp_hash_t * -parse_hash_find(pgp_stream_t *stream, const uint8_t *keyid) -{ - pgp_hashtype_t *hp; - size_t n; - - for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) { - if (memcmp(hp->keyid, keyid, PGP_KEY_ID_SIZE) == 0) { - return &hp->hash; - } - } - return NULL; -} - -/** - * \ingroup Core_Parse - * \brief Parse a version 3 signature. - * - * This function parses an version 3 signature packet, handling RSA and DSA signatures. - * - * Once the signature has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.2 - */ -static int -parse_v3_sig(pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - /* clear signature */ - (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig)); - - pkt.u.sig.info.version = PGP_V3; - - /* hash info length */ - if (!limread(&c, 1, region, stream)) { - return 0; - } - if (c != 5) { - ERRP(&stream->cbinfo, pkt, "bad hash info length"); - } - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.type = (pgp_sig_type_t)c; - /* XXX: check signature type */ - - if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) { - return 0; - } - pkt.u.sig.info.birthtime_set = 1; - - if (!limread(pkt.u.sig.info.signer_id, PGP_KEY_ID_SIZE, region, - stream)) { - return 0; - } - pkt.u.sig.info.signer_id_set = 1; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c; - /* XXX: check algorithm */ - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c; - /* XXX: check algorithm */ - - if (!limread(pkt.u.sig.hash2, 2, region, stream)) { - return 0; - } - - switch (pkt.u.sig.info.key_alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_SIGN_ONLY: - if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) { - return 0; - } - break; - - case PGP_PKA_DSA: - if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream) || - !limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) { - return 0; - } - break; - - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region, - stream) || - !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region, - stream)) { - return 0; - } - break; - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG, - "Unsupported signature key algorithm (%s)", - pgp_show_pka(pkt.u.sig.info.key_alg)); - return 0; - } - - if (region->readc != region->length) { - PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", - region->length - region->readc); - return 0; - } - if (pkt.u.sig.info.signer_id_set) { - pkt.u.sig.hash = parse_hash_find(stream, - pkt.u.sig.info.signer_id); - } - CALLBACK(PGP_PTAG_CT_SIGNATURE, &stream->cbinfo, &pkt); - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse one signature sub-packet. - * - * Version 4 signatures can have an arbitrary amount of (hashed and - * unhashed) subpackets. Subpackets are used to hold optional - * attributes of subpackets. - * - * This function parses one such signature subpacket. - * - * Once the subpacket has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire subpacket. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int -parse_one_sig_subpacket(pgp_sig_t *sig, - pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_region_t subregion; - pgp_packet_t pkt; - uint8_t bools = 0x0; - uint8_t c = 0x0; - unsigned doread = 1; - unsigned t8; - unsigned t7; - - pgp_init_subregion(&subregion, region); - if (!limited_read_new_length(&subregion.length, region, stream)) { - return 0; - } - - if (subregion.length > region->length) { - ERRP(&stream->cbinfo, pkt, "Subpacket too long"); - } - - if (!limread(&c, 1, &subregion, stream)) { - return 0; - } - - t8 = (c & 0x7f) / 8; - t7 = 1 << (c & 7); - - pkt.critical = (unsigned)c >> 7; - pkt.tag = (pgp_content_enum)(PGP_PTAG_SIG_SUBPKT_BASE + (c & 0x7f)); - - /* Application wants it delivered raw */ - if (stream->ss_raw[t8] & t7) { - pkt.u.ss_raw.tag = pkt.tag; - pkt.u.ss_raw.length = subregion.length - 1; - pkt.u.ss_raw.raw = calloc(1, pkt.u.ss_raw.length); - if (pkt.u.ss_raw.raw == NULL) { - (void) fprintf(stderr, "parse_one_sig_subpacket: bad alloc\n"); - return 0; - } - if (!limread(pkt.u.ss_raw.raw, (unsigned)pkt.u.ss_raw.length, - &subregion, stream)) { - return 0; - } - CALLBACK(PGP_PTAG_RAW_SS, &stream->cbinfo, &pkt); - return 1; - } - switch (pkt.tag) { - case PGP_PTAG_SS_CREATION_TIME: - case PGP_PTAG_SS_EXPIRATION_TIME: - case PGP_PTAG_SS_KEY_EXPIRY: - if (!limited_read_time(&pkt.u.ss_time, &subregion, stream)) - return 0; - if (pkt.tag == PGP_PTAG_SS_CREATION_TIME) { - sig->info.birthtime = pkt.u.ss_time; - sig->info.birthtime_set = 1; - } - if (pkt.tag == PGP_PTAG_SS_EXPIRATION_TIME) { - sig->info.duration = pkt.u.ss_time; - sig->info.duration_set = 1; - } - if (pkt.tag == PGP_PTAG_SS_KEY_EXPIRY) { - sig->info.key_expiry = pkt.u.ss_time; - sig->info.key_expiry_set = 1; - } - break; - - case PGP_PTAG_SS_TRUST: - if (!limread(&pkt.u.ss_trust.level, 1, &subregion, stream) || - !limread(&pkt.u.ss_trust.amount, 1, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_REVOCABLE: - if (!limread(&bools, 1, &subregion, stream)) { - return 0; - } - pkt.u.ss_revocable = !!bools; - break; - - case PGP_PTAG_SS_ISSUER_KEY_ID: - if (!limread(pkt.u.ss_issuer, PGP_KEY_ID_SIZE, &subregion, stream)) { - return 0; - } - (void) memcpy(sig->info.signer_id, pkt.u.ss_issuer, PGP_KEY_ID_SIZE); - sig->info.signer_id_set = 1; - break; - - case PGP_PTAG_SS_PREFERRED_SKA: - if (!read_data(&pkt.u.ss_skapref, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_PREFERRED_HASH: - if (!read_data(&pkt.u.ss_hashpref, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_PREF_COMPRESS: - if (!read_data(&pkt.u.ss_zpref, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_PRIMARY_USER_ID: - if (!limread(&bools, 1, &subregion, stream)) { - return 0; - } - pkt.u.ss_primary_userid = !!bools; - sig->info.primary_userid = pkt.u.ss_primary_userid; - break; - - case PGP_PTAG_SS_KEY_FLAGS: - if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) { - return 0; - } - if(pkt.u.ss_key_flags.len > 0){ - /* Only one byte is defined in rfc4880 for now */ - sig->info.key_flags = pkt.u.ss_key_flags.contents[0]; - sig->info.key_flags_set = 1; - } - break; - - case PGP_PTAG_SS_KEYSERV_PREFS: - if (!read_data(&pkt.u.ss_key_server_prefs, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_FEATURES: - if (!read_data(&pkt.u.ss_features, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_SIGNERS_USER_ID: - if (!read_unsig_str(&pkt.u.ss_signer, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_EMBEDDED_SIGNATURE: - /* \todo should do something with this sig? */ - if (!read_data(&pkt.u.ss_embedded_sig, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_NOTATION_DATA: - if (!limread_data(&pkt.u.ss_notation.flags, 4, - &subregion, stream)) { - return 0; - } - if (!limread_size_t(&pkt.u.ss_notation.name.len, 2, - &subregion, stream)) { - return 0; - } - if (!limread_size_t(&pkt.u.ss_notation.value.len, 2, - &subregion, stream)) { - return 0; - } - if (!limread_data(&pkt.u.ss_notation.name, - (unsigned)pkt.u.ss_notation.name.len, - &subregion, stream)) { - return 0; - } - if (!limread_data(&pkt.u.ss_notation.value, - (unsigned)pkt.u.ss_notation.value.len, - &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_POLICY_URI: - if (!read_string(&pkt.u.ss_policy, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_REGEXP: - if (!read_string(&pkt.u.ss_regexp, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_PREF_KEYSERV: - if (!read_string(&pkt.u.ss_keyserv, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_USERDEFINED00: - case PGP_PTAG_SS_USERDEFINED01: - case PGP_PTAG_SS_USERDEFINED02: - case PGP_PTAG_SS_USERDEFINED03: - case PGP_PTAG_SS_USERDEFINED04: - case PGP_PTAG_SS_USERDEFINED05: - case PGP_PTAG_SS_USERDEFINED06: - case PGP_PTAG_SS_USERDEFINED07: - case PGP_PTAG_SS_USERDEFINED08: - case PGP_PTAG_SS_USERDEFINED09: - case PGP_PTAG_SS_USERDEFINED10: - if (!read_data(&pkt.u.ss_userdef, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_RESERVED: - if (!read_data(&pkt.u.ss_unknown, &subregion, stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_REVOCATION_REASON: - /* first byte is the machine-readable code */ - if (!limread(&pkt.u.ss_revocation.code, 1, &subregion, stream)) { - return 0; - } - /* the rest is a human-readable UTF-8 string */ - if (!read_string(&pkt.u.ss_revocation.reason, &subregion, - stream)) { - return 0; - } - break; - - case PGP_PTAG_SS_REVOCATION_KEY: - /* octet 0 = class. Bit 0x80 must be set */ - if (!limread(&pkt.u.ss_revocation_key.class, 1, - &subregion, stream)) { - return 0; - } - if (!(pkt.u.ss_revocation_key.class & 0x80)) { - printf("Warning: PGP_PTAG_SS_REVOCATION_KEY class: " - "Bit 0x80 should be set\n"); - return 0; - } - /* octet 1 = algid */ - if (!limread(&pkt.u.ss_revocation_key.algid, 1, - &subregion, stream)) { - return 0; - } - /* octets 2-21 = fingerprint */ - if (!limread(&pkt.u.ss_revocation_key.fingerprint[0], - PGP_FINGERPRINT_SIZE, &subregion, stream)) { - return 0; - } - break; - - default: - if (stream->ss_parsed[t8] & t7) { - PGP_ERROR_1(&stream->errors, PGP_E_PROTO_UNKNOWN_SS, - "Unknown signature subpacket type (%d)", - c & 0x7f); - } - doread = 0; - break; - } - - /* Application doesn't want it delivered parsed */ - if (!(stream->ss_parsed[t8] & t7)) { - if (pkt.critical) { - PGP_ERROR_1(&stream->errors, - PGP_E_PROTO_CRITICAL_SS_IGNORED, - "Critical signature subpacket ignored (%d)", - c & 0x7f); - } - if (!doread && - !limskip(subregion.length - 1, &subregion, stream)) { - return 0; - } - if (doread) { - pgp_parser_content_free(&pkt); - } - return 1; - } - if (doread && subregion.readc != subregion.length) { - PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", - subregion.length - subregion.readc); - pgp_parser_content_free(&pkt); - return 0; - } - CALLBACK(pkt.tag, &stream->cbinfo, &pkt); - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse several signature subpackets. - * - * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set. - * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the - * entire set is consumed. - * - * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int -parse_sig_subpkts(pgp_sig_t *sig, - pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_region_t subregion; - pgp_packet_t pkt; - - pgp_init_subregion(&subregion, region); - if (!limread_scalar(&subregion.length, 2, region, stream)) { - return 0; - } - - if (subregion.length > region->length) { - ERRP(&stream->cbinfo, pkt, "Subpacket set too long"); - } - - while (subregion.readc < subregion.length) { - if (!parse_one_sig_subpacket(sig, &subregion, stream)) { - return 0; - } - } - - if (subregion.readc != subregion.length) { - if (!limskip(subregion.length - subregion.readc, - &subregion, stream)) { - ERRP(&stream->cbinfo, pkt, -"parse_sig_subpkts: subpacket length read mismatch"); - } - ERRP(&stream->cbinfo, pkt, "Subpacket length mismatch"); - } - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse a version 4 signature. - * - * This function parses a version 4 signature including all its hashed and unhashed subpackets. - * - * Once the signature packet has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int -parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "\nparse_v4_sig\n"); - } - /* clear signature */ - (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig)); - - /* - * We need to hash the packet data from version through the hashed - * subpacket data - */ - - pkt.u.sig.v4_hashstart = stream->readinfo.alength - 1; - - /* Set version,type,algorithms */ - - pkt.u.sig.info.version = PGP_V4; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.type = (pgp_sig_type_t)c; - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "signature type=%d (%s)\n", - pkt.u.sig.info.type, - pgp_show_sig_type(pkt.u.sig.info.type)); - } - /* XXX: check signature type */ - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c; - /* XXX: check key algorithm */ - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "key_alg=%d (%s)\n", - pkt.u.sig.info.key_alg, - pgp_show_pka(pkt.u.sig.info.key_alg)); - } - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c; - /* XXX: check hash algorithm */ - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "hash_alg=%d %s\n", - pkt.u.sig.info.hash_alg, - pgp_show_hash_alg(pkt.u.sig.info.hash_alg)); - } - CALLBACK(PGP_PTAG_CT_SIGNATURE_HEADER, &stream->cbinfo, &pkt); - - if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) { - return 0; - } - - pkt.u.sig.info.v4_hashlen = stream->readinfo.alength - - pkt.u.sig.v4_hashstart; - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "v4_hashlen=%zd\n", pkt.u.sig.info.v4_hashlen); - } - - /* copy hashed subpackets */ - if (pkt.u.sig.info.v4_hashed) { - free(pkt.u.sig.info.v4_hashed); - } - pkt.u.sig.info.v4_hashed = calloc(1, pkt.u.sig.info.v4_hashlen); - if (pkt.u.sig.info.v4_hashed == NULL) { - (void) fprintf(stderr, "parse_v4_sig: bad alloc\n"); - return 0; - } - - if (!stream->readinfo.accumulate) { - /* We must accumulate, else we can't check the signature */ - fprintf(stderr, "*** ERROR: must set accumulate to 1\n"); - goto error_unalloc_v4_hashed; - } - (void) memcpy(pkt.u.sig.info.v4_hashed, - stream->readinfo.accumulated + pkt.u.sig.v4_hashstart, - pkt.u.sig.info.v4_hashlen); - - if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) { - goto error_unalloc_v4_hashed; - } - - if (!limread(pkt.u.sig.hash2, 2, region, stream)) { - goto error_unalloc_v4_hashed; - } - - switch (pkt.u.sig.info.key_alg) { - case PGP_PKA_RSA: - if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) { - goto error_unalloc_v4_hashed; - } - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n"); - BN_print_fp(stderr, pkt.u.sig.info.sig.rsa.sig); - (void) fprintf(stderr, "\n"); - } - break; - - case PGP_PKA_DSA: - if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream)) { - /* - * usually if this fails, it just means we've reached - * the end of the keyring - */ - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, - "Error reading DSA r field in signature"); - } - goto error_unalloc_v4_hashed; - } - if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) { - ERRP(&stream->cbinfo, pkt, - "Error reading DSA s field in signature"); - } - break; - - case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region, - stream) || - !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region, - stream)) { - goto error_unalloc_v4_hashed; - } - break; - - case PGP_PKA_PRIVATE00: - case PGP_PKA_PRIVATE01: - case PGP_PKA_PRIVATE02: - case PGP_PKA_PRIVATE03: - case PGP_PKA_PRIVATE04: - case PGP_PKA_PRIVATE05: - case PGP_PKA_PRIVATE06: - case PGP_PKA_PRIVATE07: - case PGP_PKA_PRIVATE08: - case PGP_PKA_PRIVATE09: - case PGP_PKA_PRIVATE10: - if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) { - goto error_unalloc_v4_hashed; - } - break; - - default: - PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG, - "Bad v4 signature key algorithm (%s)", - pgp_show_pka(pkt.u.sig.info.key_alg)); - goto error_unalloc_v4_hashed; - } - if (region->readc != region->length) { - PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", - region->length - region->readc); - goto error_unalloc_v4_hashed; - } - CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt); - return 1; - -error_unalloc_v4_hashed: - free(pkt.u.sig.info.v4_hashed); - return 0; - -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse a signature subpacket. - * - * This function calls the appropriate function to handle v3 or v4 signatures. - * - * Once the signature packet has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - */ -static int -parse_sig(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (region->readc != 0) { - /* We should not have read anything so far */ - (void) fprintf(stderr, "parse_sig: bad length\n"); - return 0; - } - - (void) memset(&pkt, 0x0, sizeof(pkt)); - if (!limread(&c, 1, region, stream)) { - return 0; - } - if (c == 2 || c == 3) { - return parse_v3_sig(region, stream); - } - if (c == 4) { - return parse_v4_sig(region, stream); - } - PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_SIGNATURE_VRSN, - "Bad signature version (%d)", c); - return 0; -} - -/** - \ingroup Core_ReadPackets - \brief Parse Compressed packet -*/ -static int -parse_compressed(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - - pkt.u.compressed = (pgp_compression_type_t)c; - - CALLBACK(PGP_PTAG_CT_COMPRESSED, &stream->cbinfo, &pkt); - - /* - * The content of a compressed data packet is more OpenPGP packets - * once decompressed, so recursively handle them - */ - - return pgp_decompress(region, stream, pkt.u.compressed); -} - -/* XXX: this could be improved by sharing all hashes that are the */ -/* same, then duping them just before checking the signature. */ -static void -parse_hash_init(pgp_stream_t *stream, pgp_hash_alg_t type, - const uint8_t *keyid) -{ - pgp_hashtype_t *hash; - - hash = realloc(stream->hashes, - (stream->hashc + 1) * sizeof(*stream->hashes)); - if (hash == NULL) { - (void) fprintf(stderr, "parse_hash_init: bad alloc 0\n"); - /* just continue and die here */ - /* XXX - agc - no way to return failure */ - } else { - stream->hashes = hash; - } - hash = &stream->hashes[stream->hashc++]; - - pgp_hash_any(&hash->hash, type); - if (!hash->hash.init(&hash->hash)) { - (void) fprintf(stderr, "parse_hash_init: bad alloc\n"); - /* just continue and die here */ - /* XXX - agc - no way to return failure */ - } - (void) memcpy(hash->keyid, keyid, sizeof(hash->keyid)); -} - -/** - \ingroup Core_ReadPackets - \brief Parse a One Pass Signature packet -*/ -static int -parse_one_pass(pgp_region_t * region, pgp_stream_t * stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) { - return 0; - } - if (pkt.u.one_pass_sig.version != 3) { - PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN, - "Bad one-pass signature version (%d)", - pkt.u.one_pass_sig.version); - return 0; - } - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.one_pass_sig.sig_type = (pgp_sig_type_t)c; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.one_pass_sig.hash_alg = (pgp_hash_alg_t)c; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.one_pass_sig.key_alg = (pgp_pubkey_alg_t)c; - - if (!limread(pkt.u.one_pass_sig.keyid, - (unsigned)sizeof(pkt.u.one_pass_sig.keyid), - region, stream)) { - return 0; - } - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.one_pass_sig.nested = !!c; - CALLBACK(PGP_PTAG_CT_1_PASS_SIG, &stream->cbinfo, &pkt); - /* XXX: we should, perhaps, let the app choose whether to hash or not */ - parse_hash_init(stream, pkt.u.one_pass_sig.hash_alg, - pkt.u.one_pass_sig.keyid); - return 1; -} - -/** - \ingroup Core_ReadPackets - \brief Parse a Trust packet -*/ -static int -parse_trust(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - - if (!read_data(&pkt.u.trust, region, stream)) { - return 0; - } - CALLBACK(PGP_PTAG_CT_TRUST, &stream->cbinfo, &pkt); - return 1; -} - -static void -parse_hash_data(pgp_stream_t *stream, const void *data, - size_t length) -{ - size_t n; - - for (n = 0; n < stream->hashc; ++n) { - stream->hashes[n].hash.add(&stream->hashes[n].hash, data, (unsigned)length); - } -} - -/** - \ingroup Core_ReadPackets - \brief Parse a Literal Data packet -*/ -static int -parse_litdata(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_memory_t *mem; - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.litdata_header.format = (pgp_litdata_enum)c; - if (!limread(&c, 1, region, stream)) { - return 0; - } - if (!limread((uint8_t *)pkt.u.litdata_header.filename, - (unsigned)c, region, stream)) { - return 0; - } - pkt.u.litdata_header.filename[c] = '\0'; - if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) { - return 0; - } - CALLBACK(PGP_PTAG_CT_LITDATA_HEADER, &stream->cbinfo, &pkt); - mem = pkt.u.litdata_body.mem = pgp_memory_new(); - pgp_memory_init(pkt.u.litdata_body.mem, - (unsigned)((region->length * 101) / 100) + 12); - pkt.u.litdata_body.data = mem->buf; - - while (region->readc < region->length) { - unsigned readc = region->length - region->readc; - - if (!limread(mem->buf, readc, region, stream)) { - return 0; - } - pkt.u.litdata_body.length = readc; - parse_hash_data(stream, pkt.u.litdata_body.data, region->length); - CALLBACK(PGP_PTAG_CT_LITDATA_BODY, &stream->cbinfo, &pkt); - } - - /* XXX - get rid of mem here? */ - - return 1; -} - -/** - * \ingroup Core_Create - * - * pgp_seckey_free() frees the memory associated with "key". Note that - * the key itself is not freed. - * - * \param key - */ - -void -pgp_seckey_free(pgp_seckey_t *key) -{ - switch (key->pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - free_BN(&key->key.rsa.d); - free_BN(&key->key.rsa.p); - free_BN(&key->key.rsa.q); - free_BN(&key->key.rsa.u); - break; - - case PGP_PKA_DSA: - free_BN(&key->key.dsa.x); - break; - - default: - (void) fprintf(stderr, - "pgp_seckey_free: Unknown algorithm: %d (%s)\n", - key->pubkey.alg, - pgp_show_pka(key->pubkey.alg)); - } - free(key->checkhash); - pgp_pubkey_free(&key->pubkey); - memset(key, 0, sizeof(*key)); -} - -int -pgp_seckey_dup(pgp_seckey_t *dst, pgp_seckey_t *src) -{ - memcpy(dst, src, sizeof(*src)); - - switch (src->pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - dup_BN(&dst->key.rsa.d, src->key.rsa.d); - dup_BN(&dst->key.rsa.p, src->key.rsa.p); - dup_BN(&dst->key.rsa.q, src->key.rsa.q); - dup_BN(&dst->key.rsa.u, src->key.rsa.u); - break; - - case PGP_PKA_DSA: - dup_BN(&dst->key.dsa.x, src->key.dsa.x); - break; - - default: - (void) fprintf(stderr, - "pgp_seckey_dup: Unknown algorithm: %d (%s)\n", - src->pubkey.alg, - pgp_show_pka(src->pubkey.alg)); - return 0; - } - - if(src->checkhash) { - if ((dst->checkhash = calloc(1, PGP_CHECKHASH_SIZE)) == NULL) { - (void) fprintf(stderr, "pgp_seckey_dup: bad alloc\n"); - return 0; - }else{ - memcpy(dst->checkhash, src->checkhash, PGP_CHECKHASH_SIZE); - } - } - - pgp_pubkey_dup(&dst->pubkey, &src->pubkey); - - /*TODO alloc error handling */ - return 1; -} - -static int -consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn) -{ - pgp_packet_t pkt; - pgp_data_t remainder; - - if (region->indeterminate) { - ERRP(&stream->cbinfo, pkt, - "Can't consume indeterminate packets"); - } - - if (read_data(&remainder, region, stream)) { - /* now throw it away */ - pgp_data_free(&remainder); - if (warn) { - PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_CONSUMED, - "%s", "Warning: packet consumer"); - } - return 1; - } - PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_NOT_CONSUMED, - "%s", (warn) ? "Warning: Packet was not consumed" : - "Packet was not consumed"); - return warn; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse a secret key - */ -static int -parse_seckey(pgp_content_enum tag, pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - pgp_region_t encregion; - pgp_region_t *saved_region = NULL; - pgp_crypt_t decrypt; - pgp_hash_t checkhash; - unsigned blocksize; - unsigned crypted; - uint8_t c = 0x0; - int ret = 1; - - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "\n---------\nparse_seckey:\n"); - fprintf(stderr, - "region length=%u, readc=%u, remainder=%u\n", - region->length, region->readc, - region->length - region->readc); - } - (void) memset(&pkt, 0x0, sizeof(pkt)); - if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) { - return 0; - } - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "parse_seckey: public key parsed\n"); - //pgp_print_pubkey(&pkt.u.seckey.pubkey); - } - //stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4); - if (pkt.u.seckey.pubkey.version != PGP_V4){ - (void) fprintf(stderr, - "parse_seckey: Only V4 is supported\n"); - return 0; - } - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.seckey.s2k_usage = (pgp_s2k_usage_t)c; - - if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED || - pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) { - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.seckey.alg = (pgp_symm_alg_t)c; - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.seckey.s2k_specifier = (pgp_s2k_specifier_t)c; - switch (pkt.u.seckey.s2k_specifier) { - case PGP_S2KS_SIMPLE: - case PGP_S2KS_SALTED: - case PGP_S2KS_ITERATED_AND_SALTED: - break; - default: - (void) fprintf(stderr, - "parse_seckey: bad seckey\n"); - return 0; - } - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.seckey.hash_alg = (pgp_hash_alg_t)c; - if (pkt.u.seckey.s2k_specifier != PGP_S2KS_SIMPLE && - !limread(pkt.u.seckey.salt, 8, region, stream)) { - return 0; - } - if (pkt.u.seckey.s2k_specifier == - PGP_S2KS_ITERATED_AND_SALTED) { - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.seckey.octetc = - (16 + ((unsigned)c & 15)) << - (((unsigned)c >> 4) + 6); - } - } else if (pkt.u.seckey.s2k_usage != PGP_S2KU_NONE) { - /* this is V3 style, looks just like a V4 simple hash */ - pkt.u.seckey.alg = (pgp_symm_alg_t)c; - pkt.u.seckey.s2k_usage = PGP_S2KU_ENCRYPTED; - pkt.u.seckey.s2k_specifier = PGP_S2KS_SIMPLE; - pkt.u.seckey.hash_alg = PGP_HASH_MD5; - } - crypted = pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED || - pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED; - - if (crypted) { - pgp_packet_t seckey; - pgp_hash_t hashes[(PGP_MAX_KEY_SIZE + PGP_MIN_HASH_SIZE - 1) / PGP_MIN_HASH_SIZE]; - unsigned passlen; - uint8_t key[PGP_MAX_KEY_SIZE + PGP_MAX_HASH_SIZE]; - char *passphrase; - int hashsize; - int keysize; - int n; - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "crypted seckey\n"); - } - blocksize = pgp_block_size(pkt.u.seckey.alg); - if (blocksize == 0 || blocksize > PGP_MAX_BLOCK_SIZE) { - (void) fprintf(stderr, - "parse_seckey: bad blocksize\n"); - return 0; - } - - if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) { - return 0; - } - (void) memset(&seckey, 0x0, sizeof(seckey)); - passphrase = NULL; - seckey.u.skey_passphrase.passphrase = &passphrase; - seckey.u.skey_passphrase.seckey = &pkt.u.seckey; - CALLBACK(PGP_GET_PASSPHRASE, &stream->cbinfo, &seckey); - if (!passphrase) { - if (pgp_get_debug_level(__FILE__)) { - /* \todo make into proper error */ - (void) fprintf(stderr, - "parse_seckey: can't get passphrase\n"); - } - if (!consume_packet(region, stream, 0)) { - return 0; - } - - CALLBACK(PGP_PTAG_CT_ENCRYPTED_SECRET_KEY, - &stream->cbinfo, &pkt); - - return 1; - } - keysize = pgp_key_size(pkt.u.seckey.alg); - if (keysize == 0 || keysize > PGP_MAX_KEY_SIZE) { - (void) fprintf(stderr, - "parse_seckey: bad keysize\n"); - return 0; - } - - /* Hardcoded SHA1 for just now */ - pkt.u.seckey.hash_alg = PGP_HASH_SHA1; - hashsize = pgp_hash_size(pkt.u.seckey.hash_alg); - if (hashsize == 0 || hashsize > PGP_MAX_HASH_SIZE) { - (void) fprintf(stderr, - "parse_seckey: bad hashsize\n"); - return 0; - } - - for (n = 0; n * hashsize < keysize; ++n) { - int i; - - pgp_hash_any(&hashes[n], - pkt.u.seckey.hash_alg); - if (!hashes[n].init(&hashes[n])) { - (void) fprintf(stderr, - "parse_seckey: bad alloc\n"); - return 0; - } - /* preload hashes with zeroes... */ - for (i = 0; i < n; ++i) { - hashes[n].add(&hashes[n], - (const uint8_t *) "", 1); - } - } - passlen = (unsigned)strlen(passphrase); - for (n = 0; n * hashsize < keysize; ++n) { - unsigned i; - - switch (pkt.u.seckey.s2k_specifier) { - case PGP_S2KS_SALTED: - hashes[n].add(&hashes[n], - pkt.u.seckey.salt, - PGP_SALT_SIZE); - /* FALLTHROUGH */ - case PGP_S2KS_SIMPLE: - hashes[n].add(&hashes[n], - (uint8_t *)passphrase, (unsigned)passlen); - break; - - case PGP_S2KS_ITERATED_AND_SALTED: - for (i = 0; i < pkt.u.seckey.octetc; - i += passlen + PGP_SALT_SIZE) { - unsigned j; - - j = passlen + PGP_SALT_SIZE; - if (i + j > pkt.u.seckey.octetc && i != 0) { - j = pkt.u.seckey.octetc - i; - } - hashes[n].add(&hashes[n], - pkt.u.seckey.salt, - (unsigned)(j > PGP_SALT_SIZE) ? - PGP_SALT_SIZE : j); - if (j > PGP_SALT_SIZE) { - hashes[n].add(&hashes[n], - (uint8_t *) passphrase, - j - PGP_SALT_SIZE); - } - } - break; - default: - break; - } - } - - for (n = 0; n * hashsize < keysize; ++n) { - int r; - - r = hashes[n].finish(&hashes[n], key + n * hashsize); - if (r != hashsize) { - (void) fprintf(stderr, - "parse_seckey: bad r\n"); - return 0; - } - } - - pgp_forget(passphrase, passlen); - - pgp_crypt_any(&decrypt, pkt.u.seckey.alg); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "input iv", pkt.u.seckey.iv, pgp_block_size(pkt.u.seckey.alg)); - hexdump(stderr, "key", key, CAST_KEY_LENGTH); - } - decrypt.set_iv(&decrypt, pkt.u.seckey.iv); - decrypt.set_crypt_key(&decrypt, key); - - /* now read encrypted data */ - - pgp_reader_push_decrypt(stream, &decrypt, region); - - /* - * Since all known encryption for PGP doesn't compress, we - * can limit to the same length as the current region (for - * now). - */ - pgp_init_subregion(&encregion, NULL); - encregion.length = region->length - region->readc; - if (pkt.u.seckey.pubkey.version != PGP_V4) { - encregion.length -= 2; - } - saved_region = region; - region = &encregion; - } - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "parse_seckey: end of crypted passphrase\n"); - } - - /* XXX - Hard-coded SHA1 here ?? Check */ - if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) { - pkt.u.seckey.checkhash = calloc(1, PGP_SHA1_HASH_SIZE); - if (pkt.u.seckey.checkhash == NULL) { - (void) fprintf(stderr, "parse_seckey: bad alloc\n"); - return 0; - } - pgp_hash_sha1(&checkhash); - pgp_reader_push_hash(stream, &checkhash); - } else { - pgp_reader_push_sum16(stream); - } - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "parse_seckey: checkhash, reading MPIs\n"); - } - switch (pkt.u.seckey.pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (!limread_mpi(&pkt.u.seckey.key.rsa.d, region, stream) || - !limread_mpi(&pkt.u.seckey.key.rsa.p, region, stream) || - !limread_mpi(&pkt.u.seckey.key.rsa.q, region, stream) || - !limread_mpi(&pkt.u.seckey.key.rsa.u, region, stream)) { - ret = 0; - } - break; - - case PGP_PKA_DSA: - if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) { - ret = 0; - } - break; - - case PGP_PKA_ELGAMAL: - if (!limread_mpi(&pkt.u.seckey.key.elgamal.x, region, stream)) { - ret = 0; - } - break; - - default: - PGP_ERROR_2(&stream->errors, - PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG, - "Unsupported Public Key algorithm %d (%s)", - pkt.u.seckey.pubkey.alg, - pgp_show_pka(pkt.u.seckey.pubkey.alg)); - ret = 0; - } - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "4 MPIs read\n"); - } - //stream->reading_v3_secret = 0; - - if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) { - uint8_t hash[PGP_CHECKHASH_SIZE]; - - pgp_reader_pop_hash(stream); - checkhash.finish(&checkhash, hash); - - if (crypted && - pkt.u.seckey.pubkey.version != PGP_V4) { - pgp_reader_pop_decrypt(stream); - region = saved_region; - } - if (ret) { - if (!limread(pkt.u.seckey.checkhash, - PGP_CHECKHASH_SIZE, region, stream)) { - return 0; - } - - if (memcmp(hash, pkt.u.seckey.checkhash, - PGP_CHECKHASH_SIZE) != 0) { - ERRP(&stream->cbinfo, pkt, - "Hash mismatch in secret key"); - } - } - } else { - uint16_t sum; - - sum = pgp_reader_pop_sum16(stream); - if (crypted && - pkt.u.seckey.pubkey.version != PGP_V4) { - pgp_reader_pop_decrypt(stream); - region = saved_region; - } - if (ret) { - if (!limread_scalar(&pkt.u.seckey.checksum, 2, - region, stream)) - return 0; - - if (sum != pkt.u.seckey.checksum) { - ERRP(&stream->cbinfo, pkt, - "Checksum mismatch in secret key"); - } - } - } - - if (crypted && pkt.u.seckey.pubkey.version == PGP_V4) { - pgp_reader_pop_decrypt(stream); - } - if (region == NULL) { - (void) fprintf(stderr, "parse_seckey: NULL region\n"); - return 0; - } - if (ret && region->readc != region->length) { - (void) fprintf(stderr, "parse_seckey: bad length\n"); - return 0; - } - if (!ret) { - return 0; - } - CALLBACK(tag, &stream->cbinfo, &pkt); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "--- end of parse_seckey\n\n"); - } - return 1; -} - -/** - \ingroup Core_ReadPackets - \brief Parse a Public Key Session Key packet -*/ -static int -parse_pk_sesskey(pgp_region_t *region, - pgp_stream_t *stream) -{ - const pgp_seckey_t *secret; - pgp_packet_t sesskey; - pgp_packet_t pkt; - uint8_t *iv; - uint8_t c = 0x0; - uint8_t cs[2]; - unsigned k; - BIGNUM *g_to_k; - BIGNUM *enc_m; - int n; - uint8_t unencoded_m_buf[1024]; - - if (!limread(&c, 1, region, stream)) { - (void) fprintf(stderr, "parse_pk_sesskey - can't read char in region\n"); - return 0; - } - pkt.u.pk_sesskey.version = c; - if (pkt.u.pk_sesskey.version != 3) { - PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PKSK_VRSN, - "Bad public-key encrypted session key version (%d)", - pkt.u.pk_sesskey.version); - return 0; - } - if (!limread(pkt.u.pk_sesskey.key_id, - (unsigned)sizeof(pkt.u.pk_sesskey.key_id), region, stream)) { - return 0; - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sesskey: pubkey id", pkt.u.pk_sesskey.key_id, sizeof(pkt.u.pk_sesskey.key_id)); - } - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.pk_sesskey.alg = (pgp_pubkey_alg_t)c; - switch (pkt.u.pk_sesskey.alg) { - case PGP_PKA_RSA: - if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m, - region, stream)) { - return 0; - } - enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m; - g_to_k = NULL; - break; - - case PGP_PKA_DSA: - case PGP_PKA_ELGAMAL: - if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k, - region, stream) || - !limread_mpi( - &pkt.u.pk_sesskey.params.elgamal.encrypted_m, - region, stream)) { - return 0; - } - g_to_k = pkt.u.pk_sesskey.params.elgamal.g_to_k; - enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m; - break; - - default: - PGP_ERROR_1(&stream->errors, - PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG, - "Unknown public key algorithm in session key (%s)", - pgp_show_pka(pkt.u.pk_sesskey.alg)); - return 0; - } - - (void) memset(&sesskey, 0x0, sizeof(sesskey)); - secret = NULL; - sesskey.u.get_seckey.seckey = &secret; - sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey; - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "getting secret key via callback\n"); - } - - CALLBACK(PGP_GET_SECKEY, &stream->cbinfo, &sesskey); - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "got secret key via callback\n"); - } - if (!secret) { - CALLBACK(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo, - &pkt); - return 1; - } - n = pgp_decrypt_decode_mpi(unencoded_m_buf, - (unsigned)sizeof(unencoded_m_buf), g_to_k, enc_m, secret); - - if (n < 1) { - ERRP(&stream->cbinfo, pkt, "decrypted message too short"); - return 0; - } - - /* PKA */ - pkt.u.pk_sesskey.symm_alg = (pgp_symm_alg_t)unencoded_m_buf[0]; - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "symm alg %d\n", pkt.u.pk_sesskey.symm_alg); - } - - if (!pgp_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) { - /* ERR1P */ - PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG, - "Symmetric algorithm %s not supported", - pgp_show_symm_alg( - pkt.u.pk_sesskey.symm_alg)); - return 0; - } - k = pgp_key_size(pkt.u.pk_sesskey.symm_alg); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "key size %d\n", k); - } - - if ((unsigned) n != k + 3) { - PGP_ERROR_2(&stream->errors, PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN, - "decrypted message wrong length (got %d expected %d)", - n, k + 3); - return 0; - } - if (k > sizeof(pkt.u.pk_sesskey.key)) { - (void) fprintf(stderr, "parse_pk_sesskey: bad keylength\n"); - return 0; - } - - (void) memcpy(pkt.u.pk_sesskey.key, unencoded_m_buf + 1, k); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "recovered sesskey", pkt.u.pk_sesskey.key, k); - } - pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] + - (unencoded_m_buf[k + 2] << 8); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "session key checksum: %2x %2x\n", - unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]); - } - - /* Check checksum */ - pgp_calc_sesskey_checksum(&pkt.u.pk_sesskey, &cs[0]); - if (unencoded_m_buf[k + 1] != cs[0] || - unencoded_m_buf[k + 2] != cs[1]) { - PGP_ERROR_4(&stream->errors, PGP_E_PROTO_BAD_SK_CHECKSUM, - "Session key checksum wrong: expected %2x %2x, got %2x %2x", - cs[0], cs[1], unencoded_m_buf[k + 1], - unencoded_m_buf[k + 2]); - return 0; - } - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "getting pk session key via callback\n"); - } - /* all is well */ - CALLBACK(PGP_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "got pk session key via callback\n"); - } - - pgp_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg); - iv = calloc(1, stream->decrypt.blocksize); - if (iv == NULL) { - (void) fprintf(stderr, "parse_pk_sesskey: bad alloc\n"); - return 0; - } - stream->decrypt.set_iv(&stream->decrypt, iv); - stream->decrypt.set_crypt_key(&stream->decrypt, pkt.u.pk_sesskey.key); - pgp_encrypt_init(&stream->decrypt); - free(iv); - return 1; -} - -#if 0 -static int -decrypt_se_data(pgp_content_enum tag, pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_crypt_t *decrypt; - const int printerrors = 1; - int r = 1; - - decrypt = pgp_get_decrypt(stream); - if (decrypt) { - pgp_region_t encregion; - unsigned b = (unsigned)decrypt->blocksize; - uint8_t buf[PGP_MAX_BLOCK_SIZE + 2] = ""; - - pgp_reader_push_decrypt(stream, decrypt, region); - - pgp_init_subregion(&encregion, NULL); - encregion.length = b + 2; - - if (!exact_limread(buf, b + 2, &encregion, stream)) { - return 0; - } - if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) { - pgp_reader_pop_decrypt(stream); - PGP_ERROR_4(&stream->errors, - PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT, - "Bad symmetric decrypt (%02x%02x vs %02x%02x)", - buf[b - 2], buf[b - 1], buf[b], buf[b + 1]); - return 0; - } - if (tag == PGP_PTAG_CT_SE_DATA_BODY) { - decrypt->decrypt_resync(decrypt); - decrypt->block_encrypt(decrypt, decrypt->civ, - decrypt->civ); - } - r = pgp_parse(stream, !printerrors); - - pgp_reader_pop_decrypt(stream); - } else { - pgp_packet_t pkt; - - while (region->readc < region->length) { - unsigned len; - - len = region->length - region->readc; - if (len > sizeof(pkt.u.se_data_body.data)) - len = sizeof(pkt.u.se_data_body.data); - - if (!limread(pkt.u.se_data_body.data, len, - region, stream)) { - return 0; - } - pkt.u.se_data_body.length = len; - CALLBACK(tag, &stream->cbinfo, &pkt); - } - } - - return r; -} -#endif - -static int -decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region, - pgp_stream_t *stream) -{ - pgp_crypt_t *decrypt; - const int printerrors = 1; - int r = 1; - - decrypt = pgp_get_decrypt(stream); - if (decrypt) { - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "decrypt_se_ip_data: decrypt\n"); - } - pgp_reader_push_decrypt(stream, decrypt, region); - pgp_reader_push_se_ip_data(stream, decrypt, region); - - r = pgp_parse(stream, !printerrors); - - pgp_reader_pop_se_ip_data(stream); - pgp_reader_pop_decrypt(stream); - } else { - pgp_packet_t pkt; - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "decrypt_se_ip_data: no decrypt\n"); - } - while (region->readc < region->length) { - unsigned len; - - len = region->length - region->readc; - if (len > sizeof(pkt.u.se_data_body.data)) { - len = sizeof(pkt.u.se_data_body.data); - } - - if (!limread(pkt.u.se_data_body.data, - len, region, stream)) { - return 0; - } - - pkt.u.se_data_body.length = len; - - CALLBACK(tag, &stream->cbinfo, &pkt); - } - } - - return r; -} - -#if 0 -/** - \ingroup Core_ReadPackets - \brief Read a Symmetrically Encrypted packet -*/ -static int -parse_se_data(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - - /* there's no info to go with this, so just announce it */ - CALLBACK(PGP_PTAG_CT_SE_DATA_HEADER, &stream->cbinfo, &pkt); - - /* - * The content of an encrypted data packet is more OpenPGP packets - * once decrypted, so recursively handle them - */ - return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream); -} -#endif - -/** - \ingroup Core_ReadPackets - \brief Read a Symmetrically Encrypted Integrity Protected packet -*/ -static int -parse_se_ip_data(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - uint8_t c = 0x0; - - if (!limread(&c, 1, region, stream)) { - return 0; - } - pkt.u.se_ip_data_header = c; - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "parse_se_ip_data: data header %d\n", c); - } - if (pkt.u.se_ip_data_header != PGP_SE_IP_DATA_VERSION) { - (void) fprintf(stderr, "parse_se_ip_data: bad version\n"); - return 0; - } - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n", - region->readc, region->length); - hexdump(stderr, "compressed region", stream->readinfo.virtualpkt, stream->readinfo.virtualc); - } - /* - * The content of an encrypted data packet is more OpenPGP packets - * once decrypted, so recursively handle them - */ - return decrypt_se_ip_data(PGP_PTAG_CT_SE_IP_DATA_BODY, region, stream); -} - -/** - \ingroup Core_ReadPackets - \brief Read a MDC packet -*/ -static int -parse_mdc(pgp_region_t *region, pgp_stream_t *stream) -{ - pgp_packet_t pkt; - - pkt.u.mdc.length = PGP_SHA1_HASH_SIZE; - if ((pkt.u.mdc.data = calloc(1, PGP_SHA1_HASH_SIZE)) == NULL) { - (void) fprintf(stderr, "parse_mdc: bad alloc\n"); - return 0; - } - if (!limread(pkt.u.mdc.data, PGP_SHA1_HASH_SIZE, region, stream)) { - return 0; - } - CALLBACK(PGP_PTAG_CT_MDC, &stream->cbinfo, &pkt); - free(pkt.u.mdc.data); - return 1; -} - -/** - * \ingroup Core_ReadPackets - * \brief Parse one packet. - * - * This function parses the packet tag. It computes the value of the - * content tag and then calls the appropriate function to handle the - * content. - * - * \param *stream How to parse - * \param *pktlen On return, will contain number of bytes in packet - * \return 1 on success, 0 on error, -1 on EOF */ -static int -parse_packet(pgp_stream_t *stream, uint32_t *pktlen) -{ - pgp_packet_t pkt; - pgp_region_t region; - uint8_t ptag; - unsigned indeterminate = 0; - int ret; - - pkt.u.ptag.position = stream->readinfo.position; - - ret = base_read(&ptag, 1, stream); - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, - "parse_packet: base_read returned %d, ptag %d\n", - ret, ptag); - } - - /* errors in the base read are effectively EOF. */ - if (ret <= 0) { - return -1; - } - - *pktlen = 0; - - if (!(ptag & PGP_PTAG_ALWAYS_SET)) { - pkt.u.error = "Format error (ptag bit not set)"; - CALLBACK(PGP_PARSER_ERROR, &stream->cbinfo, &pkt); - return 0; - } - pkt.u.ptag.new_format = !!(ptag & PGP_PTAG_NEW_FORMAT); - if (pkt.u.ptag.new_format) { - pkt.u.ptag.type = (ptag & PGP_PTAG_NF_CONTENT_TAG_MASK); - pkt.u.ptag.length_type = 0; - if (!read_new_length(&pkt.u.ptag.length, stream)) { - return 0; - } - } else { - unsigned rb; - - pkt.u.ptag.type = ((unsigned)ptag & - PGP_PTAG_OF_CONTENT_TAG_MASK) - >> PGP_PTAG_OF_CONTENT_TAG_SHIFT; - pkt.u.ptag.length_type = ptag & PGP_PTAG_OF_LENGTH_TYPE_MASK; - switch (pkt.u.ptag.length_type) { - case PGP_PTAG_OLD_LEN_1: - rb = _read_scalar(&pkt.u.ptag.length, 1, stream); - break; - - case PGP_PTAG_OLD_LEN_2: - rb = _read_scalar(&pkt.u.ptag.length, 2, stream); - break; - - case PGP_PTAG_OLD_LEN_4: - rb = _read_scalar(&pkt.u.ptag.length, 4, stream); - break; - - case PGP_PTAG_OLD_LEN_INDETERMINATE: - pkt.u.ptag.length = 0; - indeterminate = 1; - rb = 1; - break; - } - if (!rb) { - return 0; - } - } - - CALLBACK(PGP_PARSER_PTAG, &stream->cbinfo, &pkt); - - pgp_init_subregion(®ion, NULL); - region.length = pkt.u.ptag.length; - region.indeterminate = indeterminate; - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "parse_packet: type %u\n", - pkt.u.ptag.type); - } - switch (pkt.u.ptag.type) { - case PGP_PTAG_CT_SIGNATURE: - ret = parse_sig(®ion, stream); - break; - - case PGP_PTAG_CT_PUBLIC_KEY: - case PGP_PTAG_CT_PUBLIC_SUBKEY: - ret = parse_pubkey((pgp_content_enum)pkt.u.ptag.type, ®ion, stream); - break; - - case PGP_PTAG_CT_TRUST: - ret = parse_trust(®ion, stream); - break; - - case PGP_PTAG_CT_USER_ID: - ret = parse_userid(®ion, stream); - break; - - case PGP_PTAG_CT_COMPRESSED: - ret = parse_compressed(®ion, stream); - break; - - case PGP_PTAG_CT_1_PASS_SIG: - ret = parse_one_pass(®ion, stream); - break; - - case PGP_PTAG_CT_LITDATA: - ret = parse_litdata(®ion, stream); - break; - - case PGP_PTAG_CT_USER_ATTR: - ret = parse_userattr(®ion, stream); - break; - - case PGP_PTAG_CT_SECRET_KEY: - case PGP_PTAG_CT_SECRET_SUBKEY: - ret = parse_seckey((pgp_content_enum)pkt.u.ptag.type, ®ion, stream); - break; - - case PGP_PTAG_CT_PK_SESSION_KEY: - ret = parse_pk_sesskey(®ion, stream); - break; - - case PGP_PTAG_CT_SE_DATA: - // SE_DATA CURRENTLY BROKEN - ret = 0; - //ret = parse_se_data(®ion, stream); - break; - - case PGP_PTAG_CT_SE_IP_DATA: - ret = parse_se_ip_data(®ion, stream); - break; - - case PGP_PTAG_CT_MDC: - ret = parse_mdc(®ion, stream); - break; - - default: - PGP_ERROR_1(&stream->errors, PGP_E_P_UNKNOWN_TAG, - "Unknown content tag 0x%x", - pkt.u.ptag.type); - ret = 0; - } - - /* Ensure that the entire packet has been consumed */ - - if (region.length != region.readc && !region.indeterminate) { - if (!consume_packet(®ion, stream, 0)) { - ret = -1; - } - } - - /* also consume it if there's been an error? */ - /* \todo decide what to do about an error on an */ - /* indeterminate packet */ - if (ret == 0) { - if (!consume_packet(®ion, stream, 0)) { - ret = -1; - } - } - /* set pktlen */ - - *pktlen = stream->readinfo.alength; - - /* do callback on entire packet, if desired and there was no error */ - - if (ret > 0 && stream->readinfo.accumulate) { - pkt.u.packet.length = stream->readinfo.alength; - pkt.u.packet.raw = stream->readinfo.accumulated; - stream->readinfo.accumulated = NULL; - stream->readinfo.asize = 0; - CALLBACK(PGP_PARSER_PACKET_END, &stream->cbinfo, &pkt); - } - stream->readinfo.alength = 0; - - return (ret < 0) ? -1 : (ret) ? 1 : 0; -} - -/** - * \ingroup Core_ReadPackets - * - * \brief Parse packets from an input stream until EOF or error. - * - * \details Setup the necessary parsing configuration in "stream" - * before calling pgp_parse(). - * - * That information includes : - * - * - a "reader" function to be used to get the data to be parsed - * - * - a "callback" function to be called when this library has identified - * a parseable object within the data - * - * - whether the calling function wants the signature subpackets - * returned raw, parsed or not at all. - * - * After returning, stream->errors holds any errors encountered while parsing. - * - * \param stream Parsing configuration - * \return 1 on success in all packets, 0 on error in any packet - * - * \sa CoreAPI Overview - * - * \sa pgp_print_errors() - * - */ - -int -pgp_parse(pgp_stream_t *stream, const int perrors) -{ - uint32_t pktlen; - int r; - - do { - r = parse_packet(stream, &pktlen); - } while (r != -1); - if (perrors) { - pgp_print_errors(stream->errors); - } - return (stream->errors == NULL); -} - -/** - * \ingroup Core_ReadPackets - * - * \brief Specifies whether one or more signature - * subpacket types should be returned parsed; or raw; or ignored. - * - * \param stream Pointer to previously allocated structure - * \param tag Packet tag. PGP_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag - * \param type Parse type - * \todo Make all packet types optional, not just subpackets */ -void -pgp_parse_options(pgp_stream_t *stream, - pgp_content_enum tag, - pgp_parse_type_t type) -{ - unsigned t7; - unsigned t8; - - if (tag == PGP_PTAG_SS_ALL) { - int n; - - for (n = 0; n < 256; ++n) { - pgp_parse_options(stream, - PGP_PTAG_SIG_SUBPKT_BASE + n, - type); - } - return; - } - if (tag < PGP_PTAG_SIG_SUBPKT_BASE || - tag > PGP_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) { - (void) fprintf(stderr, "pgp_parse_options: bad tag\n"); - return; - } - t8 = (tag - PGP_PTAG_SIG_SUBPKT_BASE) / 8; - t7 = 1 << ((tag - PGP_PTAG_SIG_SUBPKT_BASE) & 7); - switch (type) { - case PGP_PARSE_RAW: - stream->ss_raw[t8] |= t7; - stream->ss_parsed[t8] &= ~t7; - break; - - case PGP_PARSE_PARSED: - stream->ss_raw[t8] &= ~t7; - stream->ss_parsed[t8] |= t7; - break; - - case PGP_PARSE_IGNORE: - stream->ss_raw[t8] &= ~t7; - stream->ss_parsed[t8] &= ~t7; - break; - } -} - -/** -\ingroup Core_ReadPackets -\brief Free pgp_stream_t struct and its contents -*/ -void -pgp_stream_delete(pgp_stream_t *stream) -{ - pgp_cbdata_t *cbinfo; - pgp_cbdata_t *next; - pgp_cryptinfo_t *cryptinfo = &stream->cbinfo.cryptinfo; - - for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) { - next = cbinfo->next; - free(cbinfo); - } - - FREE_ARRAY(cryptinfo, recipients_key_ids); - - if (stream->readinfo.destroyer) { - stream->readinfo.destroyer(&stream->readinfo); - } - pgp_free_errors(stream->errors); - if (stream->readinfo.accumulated) { - free(stream->readinfo.accumulated); - } - free(stream); -} - -/** -\ingroup Core_ReadPackets -\brief Returns the parse_info's reader_info -\return Pointer to the reader_info inside the parse_info -*/ -pgp_reader_t * -pgp_readinfo(pgp_stream_t *stream) -{ - return &stream->readinfo; -} - -/** -\ingroup Core_ReadPackets -\brief Sets the parse_info's callback -This is used when adding the first callback in a stack of callbacks. -\sa pgp_callback_push() -*/ - -void -pgp_set_callback(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg) -{ - stream->cbinfo.cbfunc = cb; - stream->cbinfo.arg = arg; - stream->cbinfo.errors = &stream->errors; -} - -/** -\ingroup Core_ReadPackets -\brief Adds a further callback to a stack of callbacks -\sa pgp_set_callback() -*/ -void -pgp_callback_push(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg) -{ - pgp_cbdata_t *cbinfo; - - if ((cbinfo = calloc(1, sizeof(*cbinfo))) == NULL) { - (void) fprintf(stderr, "pgp_callback_push: bad alloc\n"); - return; - } - (void) memcpy(cbinfo, &stream->cbinfo, sizeof(*cbinfo)); - cbinfo->io = stream->io; - stream->cbinfo.next = cbinfo; - pgp_set_callback(stream, cb, arg); -} - -/** -\ingroup Core_ReadPackets -\brief Returns callback's arg -*/ -void * -pgp_callback_arg(pgp_cbdata_t *cbinfo) -{ - return cbinfo->arg; -} - -/** -\ingroup Core_ReadPackets -\brief Returns callback's errors -*/ -void * -pgp_callback_errors(pgp_cbdata_t *cbinfo) -{ - return cbinfo->errors; -} - -/** -\ingroup Core_ReadPackets -\brief Calls the parse_cb_info's callback if present -\return Return value from callback, if present; else PGP_FINISHED -*/ -pgp_cb_ret_t -pgp_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - return (cbinfo->cbfunc) ? cbinfo->cbfunc(pkt, cbinfo) : PGP_FINISHED; -} - -/** -\ingroup Core_ReadPackets -\brief Calls the next callback in the stack -\return Return value from callback -*/ -pgp_cb_ret_t -pgp_stacked_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - return pgp_callback(pkt, cbinfo->next); -} - -/** -\ingroup Core_ReadPackets -\brief Returns the parse_info's errors -\return parse_info's errors -*/ -pgp_error_t * -pgp_stream_get_errors(pgp_stream_t *stream) -{ - return stream->errors; -} - -pgp_crypt_t * -pgp_get_decrypt(pgp_stream_t *stream) -{ - return (stream->decrypt.alg) ? &stream->decrypt : NULL; -} diff --git a/netpgp/packet-show.c b/netpgp/packet-show.c deleted file mode 100644 index fdc4909ce7003e25106fde83bf3649c5ed65047f..0000000000000000000000000000000000000000 --- a/netpgp/packet-show.c +++ /dev/null @@ -1,491 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * - * Creates printable text strings from packet contents - * - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <stdlib.h> -#include <string.h> - -#include "netpgp/packet-show.h" - -#include "netpgp/netpgpsdk.h" -#include "netpgp/netpgpdefs.h" - - -/* - * Arrays of value->text maps - */ - -static pgp_map_t packet_tag_map[] = -{ - {PGP_PTAG_CT_RESERVED, "Reserved"}, - {PGP_PTAG_CT_PK_SESSION_KEY, "Public-Key Encrypted Session Key"}, - {PGP_PTAG_CT_SIGNATURE, "Signature"}, - {PGP_PTAG_CT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key"}, - {PGP_PTAG_CT_1_PASS_SIG, "One-Pass Signature"}, - {PGP_PTAG_CT_SECRET_KEY, "Secret Key"}, - {PGP_PTAG_CT_PUBLIC_KEY, "Public Key"}, - {PGP_PTAG_CT_SECRET_SUBKEY, "Secret Subkey"}, - {PGP_PTAG_CT_COMPRESSED, "Compressed Data"}, - {PGP_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data"}, - {PGP_PTAG_CT_MARKER, "Marker"}, - {PGP_PTAG_CT_LITDATA, "Literal Data"}, - {PGP_PTAG_CT_TRUST, "Trust"}, - {PGP_PTAG_CT_USER_ID, "User ID"}, - {PGP_PTAG_CT_PUBLIC_SUBKEY, "Public Subkey"}, - {PGP_PTAG_CT_RESERVED2, "reserved2"}, - {PGP_PTAG_CT_RESERVED3, "reserved3"}, - {PGP_PTAG_CT_USER_ATTR, "User Attribute"}, - {PGP_PTAG_CT_SE_IP_DATA, - "Symmetric Encrypted and Integrity Protected Data"}, - {PGP_PTAG_CT_MDC, "Modification Detection Code"}, - {PGP_PARSER_PTAG, "PGP_PARSER_PTAG"}, - {PGP_PTAG_RAW_SS, "PGP_PTAG_RAW_SS"}, - {PGP_PTAG_SS_ALL, "PGP_PTAG_SS_ALL"}, - {PGP_PARSER_PACKET_END, "PGP_PARSER_PACKET_END"}, - {PGP_PTAG_SIG_SUBPKT_BASE, "PGP_PTAG_SIG_SUBPKT_BASE"}, - {PGP_PTAG_SS_CREATION_TIME, "SS: Signature Creation Time"}, - {PGP_PTAG_SS_EXPIRATION_TIME, "SS: Signature Expiration Time"}, - {PGP_PTAG_SS_EXPORT_CERT, "SS: Exportable Certification"}, - {PGP_PTAG_SS_TRUST, "SS: Trust Signature"}, - {PGP_PTAG_SS_REGEXP, "SS: Regular Expression"}, - {PGP_PTAG_SS_REVOCABLE, "SS: Revocable"}, - {PGP_PTAG_SS_KEY_EXPIRY, "SS: Key Expiration Time"}, - {PGP_PTAG_SS_RESERVED, "SS: Reserved"}, - {PGP_PTAG_SS_PREFERRED_SKA, "SS: Preferred Secret Key Algorithm"}, - {PGP_PTAG_SS_REVOCATION_KEY, "SS: Revocation Key"}, - {PGP_PTAG_SS_ISSUER_KEY_ID, "SS: Issuer Key Id"}, - {PGP_PTAG_SS_NOTATION_DATA, "SS: Notation Data"}, - {PGP_PTAG_SS_PREFERRED_HASH, "SS: Preferred Hash Algorithm"}, - {PGP_PTAG_SS_PREF_COMPRESS, "SS: Preferred Compression Algorithm"}, - {PGP_PTAG_SS_KEYSERV_PREFS, "SS: Key Server Preferences"}, - {PGP_PTAG_SS_PREF_KEYSERV, "SS: Preferred Key Server"}, - {PGP_PTAG_SS_PRIMARY_USER_ID, "SS: Primary User ID"}, - {PGP_PTAG_SS_POLICY_URI, "SS: Policy URI"}, - {PGP_PTAG_SS_KEY_FLAGS, "SS: Key Flags"}, - {PGP_PTAG_SS_SIGNERS_USER_ID, "SS: Signer's User ID"}, - {PGP_PTAG_SS_REVOCATION_REASON, "SS: Reason for Revocation"}, - {PGP_PTAG_SS_FEATURES, "SS: Features"}, - {PGP_PTAG_SS_SIGNATURE_TARGET, "SS: Signature Target"}, - {PGP_PTAG_SS_EMBEDDED_SIGNATURE, "SS: Embedded Signature"}, - - {PGP_PTAG_CT_LITDATA_HEADER, "CT: Literal Data Header"}, - {PGP_PTAG_CT_LITDATA_BODY, "CT: Literal Data Body"}, - {PGP_PTAG_CT_SIGNATURE_HEADER, "CT: Signature Header"}, - {PGP_PTAG_CT_SIGNATURE_FOOTER, "CT: Signature Footer"}, - {PGP_PTAG_CT_ARMOUR_HEADER, "CT: Armour Header"}, - {PGP_PTAG_CT_ARMOUR_TRAILER, "CT: Armour Trailer"}, - {PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER, "CT: Signed Cleartext Header"}, - {PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, "CT: Signed Cleartext Body"}, - {PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, "CT: Signed Cleartext Trailer"}, - {PGP_PTAG_CT_UNARMOURED_TEXT, "CT: Unarmoured Text"}, - {PGP_PTAG_CT_ENCRYPTED_SECRET_KEY, "CT: Encrypted Secret Key"}, - {PGP_PTAG_CT_SE_DATA_HEADER, "CT: Sym Encrypted Data Header"}, - {PGP_PTAG_CT_SE_DATA_BODY, "CT: Sym Encrypted Data Body"}, - {PGP_PTAG_CT_SE_IP_DATA_HEADER, "CT: Sym Encrypted IP Data Header"}, - {PGP_PTAG_CT_SE_IP_DATA_BODY, "CT: Sym Encrypted IP Data Body"}, - {PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, "CT: Encrypted PK Session Key"}, - {PGP_GET_PASSPHRASE, "CMD: Get Secret Key Passphrase"}, - {PGP_GET_SECKEY, "CMD: Get Secret Key"}, - {PGP_PARSER_ERROR, "PGP_PARSER_ERROR"}, - {PGP_PARSER_ERRCODE, "PGP_PARSER_ERRCODE"}, - - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t ss_type_map[] = -{ - {PGP_PTAG_SS_CREATION_TIME, "Signature Creation Time"}, - {PGP_PTAG_SS_EXPIRATION_TIME, "Signature Expiration Time"}, - {PGP_PTAG_SS_TRUST, "Trust Signature"}, - {PGP_PTAG_SS_REGEXP, "Regular Expression"}, - {PGP_PTAG_SS_REVOCABLE, "Revocable"}, - {PGP_PTAG_SS_KEY_EXPIRY, "Key Expiration Time"}, - {PGP_PTAG_SS_PREFERRED_SKA, "Preferred Symmetric Algorithms"}, - {PGP_PTAG_SS_REVOCATION_KEY, "Revocation Key"}, - {PGP_PTAG_SS_ISSUER_KEY_ID, "Issuer key ID"}, - {PGP_PTAG_SS_NOTATION_DATA, "Notation Data"}, - {PGP_PTAG_SS_PREFERRED_HASH, "Preferred Hash Algorithms"}, - {PGP_PTAG_SS_PREF_COMPRESS, "Preferred Compression Algorithms"}, - {PGP_PTAG_SS_KEYSERV_PREFS, "Key Server Preferences"}, - {PGP_PTAG_SS_PREF_KEYSERV, "Preferred Key Server"}, - {PGP_PTAG_SS_PRIMARY_USER_ID, "Primary User ID"}, - {PGP_PTAG_SS_POLICY_URI, "Policy URI"}, - {PGP_PTAG_SS_KEY_FLAGS, "Key Flags"}, - {PGP_PTAG_SS_REVOCATION_REASON, "Reason for Revocation"}, - {PGP_PTAG_SS_FEATURES, "Features"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - - -static pgp_map_t ss_rr_code_map[] = -{ - {0x00, "No reason specified"}, - {0x01, "Key is superseded"}, - {0x02, "Key material has been compromised"}, - {0x03, "Key is retired and no longer used"}, - {0x20, "User ID information is no longer valid"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t sig_type_map[] = -{ - {PGP_SIG_BINARY, "Signature of a binary document"}, - {PGP_SIG_TEXT, "Signature of a canonical text document"}, - {PGP_SIG_STANDALONE, "Standalone signature"}, - {PGP_CERT_GENERIC, "Generic certification of a User ID and Public Key packet"}, - {PGP_CERT_PERSONA, "Personal certification of a User ID and Public Key packet"}, - {PGP_CERT_CASUAL, "Casual certification of a User ID and Public Key packet"}, - {PGP_CERT_POSITIVE, "Positive certification of a User ID and Public Key packet"}, - {PGP_SIG_SUBKEY, "Subkey Binding Signature"}, - {PGP_SIG_PRIMARY, "Primary Key Binding Signature"}, - {PGP_SIG_DIRECT, "Signature directly on a key"}, - {PGP_SIG_REV_KEY, "Key revocation signature"}, - {PGP_SIG_REV_SUBKEY, "Subkey revocation signature"}, - {PGP_SIG_REV_CERT, "Certification revocation signature"}, - {PGP_SIG_TIMESTAMP, "Timestamp signature"}, - {PGP_SIG_3RD_PARTY, "Third-Party Confirmation signature"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t pubkey_alg_map[] = -{ - {PGP_PKA_RSA, "RSA (Encrypt or Sign)"}, - {PGP_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only"}, - {PGP_PKA_RSA_SIGN_ONLY, "RSA Sign-Only"}, - {PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"}, - {PGP_PKA_DSA, "DSA"}, - {PGP_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"}, - {PGP_PKA_RESERVED_ECDSA, "Reserved for ECDSA"}, - {PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"}, - {PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"}, - {PGP_PKA_PRIVATE00, "Private/Experimental"}, - {PGP_PKA_PRIVATE01, "Private/Experimental"}, - {PGP_PKA_PRIVATE02, "Private/Experimental"}, - {PGP_PKA_PRIVATE03, "Private/Experimental"}, - {PGP_PKA_PRIVATE04, "Private/Experimental"}, - {PGP_PKA_PRIVATE05, "Private/Experimental"}, - {PGP_PKA_PRIVATE06, "Private/Experimental"}, - {PGP_PKA_PRIVATE07, "Private/Experimental"}, - {PGP_PKA_PRIVATE08, "Private/Experimental"}, - {PGP_PKA_PRIVATE09, "Private/Experimental"}, - {PGP_PKA_PRIVATE10, "Private/Experimental"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t symm_alg_map[] = -{ - {PGP_SA_PLAINTEXT, "Plaintext or unencrypted data"}, - {PGP_SA_IDEA, "IDEA"}, - {PGP_SA_TRIPLEDES, "TripleDES"}, - {PGP_SA_CAST5, "CAST5"}, - {PGP_SA_BLOWFISH, "Blowfish"}, - {PGP_SA_AES_128, "AES (128-bit key)"}, - {PGP_SA_AES_192, "AES (192-bit key)"}, - {PGP_SA_AES_256, "AES (256-bit key)"}, - {PGP_SA_TWOFISH, "Twofish(256-bit key)"}, - {PGP_SA_CAMELLIA_128, "Camellia (128-bit key)"}, - {PGP_SA_CAMELLIA_192, "Camellia (192-bit key)"}, - {PGP_SA_CAMELLIA_256, "Camellia (256-bit key)"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t hash_alg_map[] = -{ - {PGP_HASH_MD5, "MD5"}, - {PGP_HASH_SHA1, "SHA1"}, - {PGP_HASH_RIPEMD, "RIPEMD160"}, - {PGP_HASH_SHA256, "SHA256"}, - {PGP_HASH_SHA384, "SHA384"}, - {PGP_HASH_SHA512, "SHA512"}, - {PGP_HASH_SHA224, "SHA224"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -static pgp_map_t compression_alg_map[] = -{ - {PGP_C_NONE, "Uncompressed"}, - {PGP_C_ZIP, "ZIP(RFC1951)"}, - {PGP_C_ZLIB, "ZLIB(RFC1950)"}, - {PGP_C_BZIP2, "Bzip2(BZ2)"}, - {0x00, NULL}, /* this is the end-of-array marker */ -}; - -/* - * Private functions - */ - -static void -list_init(pgp_list_t *list) -{ - list->size = 0; - list->used = 0; - list->strings = NULL; -} - -static void -list_free_strings(pgp_list_t *list) -{ - unsigned i; - - for (i = 0; i < list->used; i++) { - free(list->strings[i]); - list->strings[i] = NULL; - } -} - -static void -list_free(pgp_list_t *list) -{ - if (list->strings) - free(list->strings); - list_init(list); -} - -/* find a bitfield in a map - serial search */ -static const char * -find_bitfield(pgp_bit_map_t *map, uint8_t octet) -{ - pgp_bit_map_t *row; - - for (row = map; row->string != NULL && row->mask != octet ; row++) { - } - return (row->string) ? row->string : "Unknown"; -} - -/* ! generic function to initialise pgp_text_t structure */ -void -pgp_text_init(pgp_text_t *text) -{ - list_init(&text->known); - list_init(&text->unknown); -} - -/** - * \ingroup Core_Print - * - * pgp_text_free() frees the memory used by an pgp_text_t structure - * - * \param text Pointer to a previously allocated structure. This structure and its contents will be freed. - */ -void -pgp_text_free(pgp_text_t *text) -{ - /* Strings in "known" array will be constants, so don't free them */ - list_free(&text->known); - - /* - * Strings in "unknown" array will be dynamically allocated, so do - * free them - */ - list_free_strings(&text->unknown); - list_free(&text->unknown); - - free(text); -} - -/* - * Public Functions - */ - -/** - * \ingroup Core_Print - * returns description of the Packet Tag - * \param packet_tag - * \return string or "Unknown" -*/ -const char * -pgp_show_packet_tag(pgp_content_enum packet_tag) -{ - const char *ret; - - ret = pgp_str_from_map(packet_tag, packet_tag_map); - if (!ret) { - ret = "Unknown Tag"; - } - return ret; -} - -/** - * \ingroup Core_Print - * - * returns description of the Signature Sub-Packet type - * \param ss_type Signature Sub-Packet type - * \return string or "Unknown" - */ -const char * -pgp_show_ss_type(pgp_content_enum ss_type) -{ - return pgp_str_from_map(ss_type, ss_type_map); -} - -/** - * \ingroup Core_Print - * - * returns description of the Revocation Reason code - * \param ss_rr_code Revocation Reason code - * \return string or "Unknown" - */ -const char * -pgp_show_ss_rr_code(pgp_ss_rr_code_t ss_rr_code) -{ - return pgp_str_from_map(ss_rr_code, ss_rr_code_map); -} - -/** - * \ingroup Core_Print - * - * returns description of the given Signature type - * \param sig_type Signature type - * \return string or "Unknown" - */ -const char * -pgp_show_sig_type(pgp_sig_type_t sig_type) -{ - return pgp_str_from_map(sig_type, sig_type_map); -} - -/** - * \ingroup Core_Print - * - * returns description of the given Public Key Algorithm - * \param pka Public Key Algorithm type - * \return string or "Unknown" - */ -const char * -pgp_show_pka(pgp_pubkey_alg_t pka) -{ - return pgp_str_from_map(pka, pubkey_alg_map); -} - -/** - * \ingroup Core_Print - * returns description of the Preferred Compression - * \param octet Preferred Compression - * \return string or "Unknown" -*/ -const char * -pgp_show_ss_zpref(uint8_t octet) -{ - return pgp_str_from_map(octet, compression_alg_map); -} - -/** - * \ingroup Core_Print - * - * returns description of the Hash Algorithm type - * \param hash Hash Algorithm type - * \return string or "Unknown" - */ -const char * -pgp_show_hash_alg(uint8_t hash) -{ - return pgp_str_from_map(hash, hash_alg_map); -} - -const char * -pgp_show_symm_alg(uint8_t hash) -{ - return pgp_str_from_map(hash, symm_alg_map); -} - -/** - * \ingroup Core_Print - * returns description of the given Preferred Symmetric Key Algorithm - * \param octet - * \return string or "Unknown" -*/ -const char * -pgp_show_ss_skapref(uint8_t octet) -{ - return pgp_str_from_map(octet, symm_alg_map); -} - -/** - * \ingroup Core_Print - * returns description of SS Key Flag - * \param octet - * \param map - * \return -*/ -const char * -pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map) -{ - return find_bitfield(map, octet); -} - -/** - * \ingroup Core_Print - * - * returns description of one given Key Server Preference - * - * \param prefs Byte containing bitfield of preferences - * \param map - * \return string or "Unknown" - */ -const char * -pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map) -{ - return find_bitfield(map, prefs); -} - diff --git a/netpgp/reader.c b/netpgp/reader.c deleted file mode 100644 index f2fde6366f027dc72ed98a427ee4a1ffec729687..0000000000000000000000000000000000000000 --- a/netpgp/reader.c +++ /dev/null @@ -1,2395 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_DIRECT_H -#include <direct.h> -#endif - -#ifdef HAVE_INTTYPES_H -#include <inttypes.h> -#endif - -#ifdef HAVE_OPENSSL_IDEA_H -#include <openssl/cast.h> -#endif - -#ifdef HAVE_OPENSSL_IDEA_H -#include <openssl/idea.h> -#endif - -#ifdef HAVE_OPENSSL_AES_H -#include <openssl/aes.h> -#endif - -#ifdef HAVE_OPENSSL_DES_H -#include <openssl/des.h> -#endif - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif - -#include "netpgp/errors.h" -#include "netpgp/crypto.h" -#include "netpgp/create.h" -#include "netpgp/signature.h" -#include "netpgp/packet.h" -#include "netpgp/packet-parse.h" -#include "netpgp/packet-show.h" -#include "netpgp/packet.h" -#include "netpgp/keyring.h" -#include "netpgp/readerwriter.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/netpgpdigest.h" - - -/* get a pass phrase from the user */ -int -pgp_getpassphrase(void *in, char *phrase, size_t size) -{ - char *p; - - if (in == NULL) { - while ((p = getpass("netpgp passphrase: ")) == NULL) { - } - (void) snprintf(phrase, size, "%s", p); - } else { - if (fgets(phrase, (int)size, in) == NULL) { - return 0; - } - phrase[strlen(phrase) - 1] = 0x0; - } - return 1; -} - -/** - * \ingroup Internal_Readers_Generic - * \brief Starts reader stack - * \param stream Parse settings - * \param reader Reader to use - * \param destroyer Destroyer to use - * \param vp Reader-specific arg - */ -void -pgp_reader_set(pgp_stream_t *stream, - pgp_reader_func_t *reader, - pgp_reader_destroyer_t *destroyer, - void *vp) -{ - stream->readinfo.reader = reader; - stream->readinfo.destroyer = destroyer; - stream->readinfo.arg = vp; -} - -/** - * \ingroup Internal_Readers_Generic - * \brief Adds to reader stack - * \param stream Parse settings - * \param reader Reader to use - * \param destroyer Reader's destroyer - * \param vp Reader-specific arg - */ -void -pgp_reader_push(pgp_stream_t *stream, - pgp_reader_func_t *reader, - pgp_reader_destroyer_t *destroyer, - void *vp) -{ - pgp_reader_t *readinfo; - - if ((readinfo = calloc(1, sizeof(*readinfo))) == NULL) { - (void) fprintf(stderr, "pgp_reader_push: bad alloc\n"); - } else { - *readinfo = stream->readinfo; - (void) memset(&stream->readinfo, 0x0, sizeof(stream->readinfo)); - stream->readinfo.next = readinfo; - stream->readinfo.parent = stream; - - /* should copy accumulate flags from other reader? RW */ - stream->readinfo.accumulate = readinfo->accumulate; - - pgp_reader_set(stream, reader, destroyer, vp); - } -} - -/** - * \ingroup Internal_Readers_Generic - * \brief Removes from reader stack - * \param stream Parse settings - */ -void -pgp_reader_pop(pgp_stream_t *stream) -{ - pgp_reader_t *next = stream->readinfo.next; - - if (stream->readinfo.accumulate && stream->readinfo.asize > 0) { - free(stream->readinfo.accumulated); - } - - stream->readinfo = *next; - free(next); -} - -/** - * \ingroup Internal_Readers_Generic - * \brief Gets arg from reader - * \param readinfo Reader info - * \return Pointer to reader info's arg - */ -void * -pgp_reader_get_arg(pgp_reader_t *readinfo) -{ - return readinfo->arg; -} - -/**************************************************************************/ - -#define CRC24_POLY 0x1864cfbL - -enum { - NONE = 0, - BEGIN_PGP_MESSAGE, - BEGIN_PGP_PUBLIC_KEY_BLOCK, - BEGIN_PGP_PRIVATE_KEY_BLOCK, - BEGIN_PGP_MULTI, - BEGIN_PGP_SIGNATURE, - - END_PGP_MESSAGE, - END_PGP_PUBLIC_KEY_BLOCK, - END_PGP_PRIVATE_KEY_BLOCK, - END_PGP_MULTI, - END_PGP_SIGNATURE, - - BEGIN_PGP_SIGNED_MESSAGE -}; - -/** - * \struct dearmour_t - */ -typedef struct { - enum { - OUTSIDE_BLOCK = 0, - BASE64, - AT_TRAILER_NAME - } state; - int lastseen; - pgp_stream_t *parse_info; - unsigned seen_nl:1; - unsigned prev_nl:1; - unsigned allow_headers_without_gap:1; - /* !< allow headers in armoured data that are - * not separated from the data by a blank line - * */ - unsigned allow_no_gap:1; - /* !< allow no blank line at the start of - * armoured data */ - unsigned allow_trailing_whitespace:1; - /* !< allow armoured stuff to have trailing - * whitespace where we wouldn't strictly expect - * it */ - /* it is an error to get a cleartext message without a sig */ - unsigned expect_sig:1; - unsigned got_sig:1; - /* base64 stuff */ - unsigned buffered; - uint8_t buffer[3]; - unsigned eof64; - uint32_t checksum; - uint32_t read_checksum; - /* unarmoured text blocks */ - uint8_t unarmoured[NETPGP_BUFSIZ]; - size_t unarmoredc; - /* pushed back data (stored backwards) */ - uint8_t *pushback; - unsigned pushbackc; - /* armoured block headers */ - pgp_headers_t headers; -} dearmour_t; - -static void -push_back(dearmour_t *dearmour, const uint8_t *buf, - unsigned length) -{ - unsigned n; - - if (dearmour->pushback) { - (void) fprintf(stderr, "push_back: already pushed back\n"); - } else if ((dearmour->pushback = calloc(1, length)) == NULL) { - (void) fprintf(stderr, "push_back: bad alloc\n"); - } else { - for (n = 0; n < length; ++n) { - dearmour->pushback[n] = buf[(length - n) - 1]; - } - dearmour->pushbackc = length; - } -} - -/* this struct holds a textual header line */ -typedef struct headerline_t { - const char *s; /* the header line */ - size_t len; /* its length */ - int type; /* the defined type */ -} headerline_t; - -static headerline_t headerlines[] = { - { "BEGIN PGP MESSAGE", 17, BEGIN_PGP_MESSAGE }, - { "BEGIN PGP PUBLIC KEY BLOCK", 26, BEGIN_PGP_PUBLIC_KEY_BLOCK }, - { "BEGIN PGP PRIVATE KEY BLOCK",27, BEGIN_PGP_PRIVATE_KEY_BLOCK }, - { "BEGIN PGP MESSAGE, PART ", 25, BEGIN_PGP_MULTI }, - { "BEGIN PGP SIGNATURE", 19, BEGIN_PGP_SIGNATURE }, - - { "END PGP MESSAGE", 15, END_PGP_MESSAGE }, - { "END PGP PUBLIC KEY BLOCK", 24, END_PGP_PUBLIC_KEY_BLOCK }, - { "END PGP PRIVATE KEY BLOCK", 25, END_PGP_PRIVATE_KEY_BLOCK }, - { "END PGP MESSAGE, PART ", 22, END_PGP_MULTI }, - { "END PGP SIGNATURE", 17, END_PGP_SIGNATURE }, - - { "BEGIN PGP SIGNED MESSAGE", 24, BEGIN_PGP_SIGNED_MESSAGE }, - - { NULL, 0, -1 } -}; - -/* search through the table of header lines */ -static int -findheaderline(char *headerline) -{ - headerline_t *hp; - - for (hp = headerlines ; hp->s ; hp++) { - if (strncmp(headerline, hp->s, hp->len) == 0) { - break; - } - } - return hp->type; -} - -static int -set_lastseen_headerline(dearmour_t *dearmour, char *hdr, pgp_error_t **errors) -{ - int lastseen; - int prev; - - prev = dearmour->lastseen; - if ((lastseen = findheaderline(hdr)) == -1) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "Unrecognised Header Line %s", hdr); - return 0; - } - dearmour->lastseen = lastseen; - if (pgp_get_debug_level(__FILE__)) { - printf("set header: hdr=%s, dearmour->lastseen=%d, prev=%d\n", - hdr, dearmour->lastseen, prev); - } - switch (dearmour->lastseen) { - case NONE: - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "Unrecognised last seen Header Line %s", hdr); - break; - - case END_PGP_MESSAGE: - if (prev != BEGIN_PGP_MESSAGE) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Got END PGP MESSAGE, but not after BEGIN"); - } - break; - - case END_PGP_PUBLIC_KEY_BLOCK: - if (prev != BEGIN_PGP_PUBLIC_KEY_BLOCK) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Got END PGP PUBLIC KEY BLOCK, but not after BEGIN"); - } - break; - - case END_PGP_PRIVATE_KEY_BLOCK: - if (prev != BEGIN_PGP_PRIVATE_KEY_BLOCK) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Got END PGP PRIVATE KEY BLOCK, but not after BEGIN"); - } - break; - - case BEGIN_PGP_MULTI: - case END_PGP_MULTI: - PGP_ERROR_1(errors, PGP_E_R_UNSUPPORTED, "%s", - "Multi-part messages are not yet supported"); - break; - - case END_PGP_SIGNATURE: - if (prev != BEGIN_PGP_SIGNATURE) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Got END PGP SIGNATURE, but not after BEGIN"); - } - break; - - case BEGIN_PGP_MESSAGE: - case BEGIN_PGP_PUBLIC_KEY_BLOCK: - case BEGIN_PGP_PRIVATE_KEY_BLOCK: - case BEGIN_PGP_SIGNATURE: - case BEGIN_PGP_SIGNED_MESSAGE: - break; - } - return 1; -} - -static int -read_char(pgp_stream_t *stream, dearmour_t *dearmour, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo, - unsigned skip) -{ - uint8_t c; - - do { - if (dearmour->pushbackc) { - if (!dearmour->pushback) { - return -1; - } - c = dearmour->pushback[--dearmour->pushbackc]; - if (dearmour->pushbackc == 0) { - free(dearmour->pushback); - dearmour->pushback = NULL; - } - } else if (pgp_stacked_read(stream, &c, 1, errors, readinfo, - cbinfo) != 1) { - return -1; - } - } while (skip && c == '\r'); - dearmour->prev_nl = dearmour->seen_nl; - dearmour->seen_nl = c == '\n'; - return c; -} - -static int -eat_whitespace(pgp_stream_t *stream, int first, - dearmour_t *dearmour, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo, - unsigned skip) -{ - int c = first; - - while (c == ' ' || c == '\t') { - c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip); - } - return c; -} - -static int -read_and_eat_whitespace(pgp_stream_t *stream, dearmour_t *dearmour, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo, - unsigned skip) -{ - int c; - - do { - c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip); - } while (c == ' ' || c == '\t'); - return c; -} - -static void -flush(dearmour_t *dearmour, pgp_cbdata_t *cbinfo) -{ - pgp_packet_t content; - - if (dearmour->unarmoredc > 0) { - content.u.unarmoured_text.data = dearmour->unarmoured; - content.u.unarmoured_text.length = (unsigned)dearmour->unarmoredc; - CALLBACK(PGP_PTAG_CT_UNARMOURED_TEXT, cbinfo, &content); - dearmour->unarmoredc = 0; - } -} - -static int -unarmoured_read_char(pgp_stream_t *stream, dearmour_t *dearmour, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo, - unsigned skip) -{ - int c; - - do { - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0); - if (c < 0) { - return c; - } - dearmour->unarmoured[dearmour->unarmoredc++] = c; - if (dearmour->unarmoredc == sizeof(dearmour->unarmoured)) { - flush(dearmour, cbinfo); - } - } while (skip && c == '\r'); - return c; -} - -/** - * \param headers - * \param key - * - * \return header value if found, otherwise NULL - */ -static const char * -find_header(pgp_headers_t *headers, const char *key) -{ - unsigned n; - - for (n = 0; n < headers->headerc; ++n) { - if (strcmp(headers->headers[n].key, key) == 0) { - return headers->headers[n].value; - } - } - return NULL; -} - -/** - * \param dest - * \param src - */ -static void -dup_headers(pgp_headers_t *dest, const pgp_headers_t *src) -{ - unsigned n; - - if ((dest->headers = calloc(src->headerc, sizeof(*dest->headers))) == NULL) { - (void) fprintf(stderr, "dup_headers: bad alloc\n"); - } else { - dest->headerc = src->headerc; - for (n = 0; n < src->headerc; ++n) { - dest->headers[n].key = netpgp_strdup(src->headers[n].key); - dest->headers[n].value = netpgp_strdup(src->headers[n].value); - } - } -} - -/* - * Note that this skips CRs so implementations always see just straight LFs - * as line terminators - */ -static int -process_dash_escaped(pgp_stream_t *stream, dearmour_t *dearmour, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - pgp_fixed_body_t *body; - pgp_packet_t content2; - pgp_packet_t content; - const char *hashstr; - pgp_hash_t *hash; - int total; - - body = &content.u.cleartext_body; - if ((hash = calloc(1, sizeof(*hash))) == NULL) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "process_dash_escaped: bad alloc"); - return -1; - } - hashstr = find_header(&dearmour->headers, "Hash"); - if (hashstr) { - pgp_hash_alg_t alg; - - alg = pgp_str_to_hash_alg(hashstr); - if (!pgp_is_hash_alg_supported(&alg)) { - free(hash); - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "Unsupported hash algorithm '%s'", hashstr); - return -1; - } - if (alg == PGP_HASH_UNKNOWN) { - free(hash); - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "Unknown hash algorithm '%s'", hashstr); - return -1; - } - pgp_hash_any(hash, alg); - } else { - pgp_hash_md5(hash); - } - - if (!hash->init(hash)) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "can't initialise hash"); - return -1; - } - - body->length = 0; - total = 0; - for (;;) { - int c; - unsigned count; - - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1); - if (c < 0) { - return -1; - } - if (dearmour->prev_nl && c == '-') { - if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, - 0)) < 0) { - return -1; - } - if (c != ' ') { - /* then this had better be a trailer! */ - if (c != '-') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Bad dash-escaping"); - } - for (count = 2; count < 5; ++count) { - if ((c = read_char(stream, dearmour, errors, - readinfo, cbinfo, 0)) < 0) { - return -1; - } - if (c != '-') { - PGP_ERROR_1(errors, - PGP_E_R_BAD_FORMAT, "%s", - "Bad dash-escaping (2)"); - } - } - dearmour->state = AT_TRAILER_NAME; - break; - } - /* otherwise we read the next character */ - if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, - 0)) < 0) { - return -1; - } - } - if (c == '\n' && body->length) { - if (memchr(body->data + 1, '\n', body->length - 1) - != NULL) { - (void) fprintf(stderr, - "process_dash_escaped: newline found\n"); - return -1; - } - if (body->data[0] == '\n') { - hash->add(hash, (const uint8_t *)"\r", 1); - } - hash->add(hash, body->data, body->length); - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "Got body:\n%s\n", body->data); - } - CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo, - &content); - body->length = 0; - } - body->data[body->length++] = c; - total += 1; - if (body->length == sizeof(body->data)) { - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "Got body (2):\n%s\n", - body->data); - } - CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo, - &content); - body->length = 0; - } - } - if (body->data[0] != '\n') { - (void) fprintf(stderr, - "process_dash_escaped: no newline in body data\n"); - return -1; - } - if (body->length != 1) { - (void) fprintf(stderr, - "process_dash_escaped: bad body length\n"); - return -1; - } - /* don't send that one character, because it's part of the trailer */ - (void) memset(&content2, 0x0, sizeof(content2)); - CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, cbinfo, &content2); - return total; -} - -static int -add_header(dearmour_t *dearmour, const char *key, const char *value) -{ - int n; - - /* - * Check that the header is valid - */ - if (strcmp(key, "Version") == 0 || - strcmp(key, "Comment") == 0 || - strcmp(key, "MessageID") == 0 || - strcmp(key, "Hash") == 0 || - strcmp(key, "Charset") == 0) { - n = dearmour->headers.headerc; - dearmour->headers.headers = realloc(dearmour->headers.headers, - (n + 1) * sizeof(*dearmour->headers.headers)); - if (dearmour->headers.headers == NULL) { - (void) fprintf(stderr, "add_header: bad alloc\n"); - return 0; - } - dearmour->headers.headers[n].key = netpgp_strdup(key); - dearmour->headers.headers[n].value = netpgp_strdup(value); - dearmour->headers.headerc = n + 1; - return 1; - } - return 0; -} - -/* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */ -static int -parse_headers(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors, - pgp_reader_t * readinfo, pgp_cbdata_t * cbinfo) -{ - unsigned nbuf; - unsigned size; - unsigned first = 1; - char *buf; - int ret = 1; - - nbuf = 0; - size = 80; - if ((buf = calloc(1, size)) == NULL) { - (void) fprintf(stderr, "parse_headers: bad calloc\n"); - return -1; - } - for (;;) { - int c; - - if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1)) < 0) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Unexpected EOF"); - ret = -1; - break; - } - if (c == '\n') { - char *s; - - if (nbuf == 0) { - break; - } - - if (nbuf >= size) { - (void) fprintf(stderr, - "parse_headers: bad size\n"); - return -1; - } - buf[nbuf] = '\0'; - - if ((s = strchr(buf, ':')) == NULL) { - if (!first && !dearmour->allow_headers_without_gap) { - /* - * then we have seriously malformed - * armour - */ - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "No colon in armour header"); - ret = -1; - break; - } else { - if (first && - !(dearmour->allow_headers_without_gap || dearmour->allow_no_gap)) { - PGP_ERROR_1(errors, - PGP_E_R_BAD_FORMAT, - "%s", "No colon in" - " armour header (2)"); - /* - * then we have a nasty - * armoured block with no - * headers, not even a blank - * line. - */ - buf[nbuf] = '\n'; - push_back(dearmour, (uint8_t *) buf, nbuf + 1); - ret = -1; - break; - } - } - } else { - *s = '\0'; - if (s[1] != ' ') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "No space in armour header"); - ret = -1; - goto end; - } - if (!add_header(dearmour, buf, s + 2)) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "Invalid header %s", buf); - ret = -1; - goto end; - } - nbuf = 0; - } - first = 0; - } else { - if (size <= nbuf + 1) { - size += size + 80; - buf = realloc(buf, size); - if (buf == NULL) { - (void) fprintf(stderr, "bad alloc\n"); - ret = -1; - goto end; - } - } - buf[nbuf++] = c; - } - } - -end: - free(buf); - - return ret; -} - -static int -read4(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo, - int *pc, unsigned *pn, uint32_t *pl) -{ - int n = 0, c = 0; - uint32_t l = 0; - - for (n = 0; n < 4; ++n) { - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1); - if (c < 0) { - dearmour->eof64 = 1; - return -1; - } - if (c == '-' || c == '=') { - break; - } - l <<= 6; - if (c >= 'A' && c <= 'Z') { - l += (uint32_t)(c - 'A'); - } else if (c >= 'a' && c <= 'z') { - l += (uint32_t)(c - 'a') + 26; - } else if (c >= '0' && c <= '9') { - l += (uint32_t)(c - '0') + 52; - } else if (c == '+') { - l += 62; - } else if (c == '/') { - l += 63; - } else { - --n; - l >>= 6; - } - } - - *pc = c; - *pn = n; - *pl = l; - - return 4; -} - -unsigned -pgp_crc24(unsigned checksum, uint8_t c) -{ - unsigned i; - - checksum ^= c << 16; - for (i = 0; i < 8; i++) { - checksum <<= 1; - if (checksum & 0x1000000) - checksum ^= CRC24_POLY; - } - return (unsigned)(checksum & 0xffffffL); -} - -static int -decode64(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - unsigned n; - int n2; - uint32_t l; - int c; - int ret; - - if (dearmour->buffered) { - (void) fprintf(stderr, "decode64: bad dearmour->buffered\n"); - return 0; - } - - ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n, &l); - if (ret < 0) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Badly formed base64"); - return 0; - } - if (n == 3) { - if (c != '=') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Badly terminated base64 (2)"); - return 0; - } - dearmour->buffered = 2; - dearmour->eof64 = 1; - l >>= 2; - } else if (n == 2) { - if (c != '=') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Badly terminated base64 (3)"); - return 0; - } - dearmour->buffered = 1; - dearmour->eof64 = 1; - l >>= 4; - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0); - if (c != '=') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Badly terminated base64"); - return 0; - } - } else if (n == 0) { - if (!dearmour->prev_nl || c != '=') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Badly terminated base64 (4)"); - return 0; - } - dearmour->buffered = 0; - } else { - if (n != 4) { - (void) fprintf(stderr, - "decode64: bad n (!= 4)\n"); - return 0; - } - dearmour->buffered = 3; - if (c == '-' || c == '=') { - (void) fprintf(stderr, "decode64: bad c\n"); - return 0; - } - } - - if (dearmour->buffered < 3 && dearmour->buffered > 0) { - /* then we saw padding */ - if (c != '=') { - (void) fprintf(stderr, "decode64: bad c (=)\n"); - return 0; - } - c = read_and_eat_whitespace(stream, dearmour, errors, readinfo, cbinfo, - 1); - if (c != '\n') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "No newline at base64 end"); - return 0; - } - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0); - if (c != '=') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "No checksum at base64 end"); - return 0; - } - } - if (c == '=') { - /* now we are at the checksum */ - ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n, - &dearmour->read_checksum); - if (ret < 0 || n != 4) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Error in checksum"); - return 0; - } - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1); - if (dearmour->allow_trailing_whitespace) - c = eat_whitespace(stream, c, dearmour, errors, readinfo, cbinfo, - 1); - if (c != '\n') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Badly terminated checksum"); - return 0; - } - c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0); - if (c != '-') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Bad base64 trailer (2)"); - return 0; - } - } - if (c == '-') { - for (n = 0; n < 4; ++n) - if (read_char(stream, dearmour, errors, readinfo, cbinfo, - 0) != '-') { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Bad base64 trailer"); - return 0; - } - dearmour->eof64 = 1; - } else { - if (!dearmour->buffered) { - (void) fprintf(stderr, "decode64: not buffered\n"); - return 0; - } - } - - for (n = 0; n < dearmour->buffered; ++n) { - dearmour->buffer[n] = (uint8_t)l; - l >>= 8; - } - - for (n2 = dearmour->buffered - 1; n2 >= 0; --n2) - dearmour->checksum = pgp_crc24((unsigned)dearmour->checksum, - dearmour->buffer[n2]); - - if (dearmour->eof64 && dearmour->read_checksum != dearmour->checksum) { - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Checksum mismatch"); - return 0; - } - return 1; -} - -static void -base64(dearmour_t *dearmour) -{ - dearmour->state = BASE64; - dearmour->checksum = CRC24_INIT; - dearmour->eof64 = 0; - dearmour->buffered = 0; -} - -/* This reader is rather strange in that it can generate callbacks for */ -/* content - this is because plaintext is not encapsulated in PGP */ -/* packets... it also calls back for the text between the blocks. */ - -static int -armoured_data_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - pgp_packet_t content; - dearmour_t *dearmour; - unsigned first; - uint8_t *dest = dest_; - char buf[1024]; - int saved; - int ret; - - dearmour = pgp_reader_get_arg(readinfo); - saved = (int)length; - if (dearmour->eof64 && !dearmour->buffered) { - if (dearmour->state != OUTSIDE_BLOCK && - dearmour->state != AT_TRAILER_NAME) { - (void) fprintf(stderr, - "armoured_data_reader: bad dearmour state\n"); - return 0; - } - } - - while (length > 0) { - unsigned count; - unsigned n; - int c; - - flush(dearmour, cbinfo); - switch (dearmour->state) { - case OUTSIDE_BLOCK: - /* - * This code returns EOF rather than EARLY_EOF - * because if we don't see a header line at all, then - * it is just an EOF (and not a BLOCK_END) - */ - while (!dearmour->seen_nl) { - if ((c = unarmoured_read_char(stream, dearmour, errors, - readinfo, cbinfo, 1)) < 0) { - return 0; - } - } - - /* - * flush at this point so we definitely have room for - * the header, and so we can easily erase it from the - * buffer - */ - flush(dearmour, cbinfo); - /* Find and consume the 5 leading '-' */ - for (count = 0; count < 5; ++count) { - if ((c = unarmoured_read_char(stream, dearmour, errors, - readinfo, cbinfo, 0)) < 0) { - return 0; - } - if (c != '-') { - goto reloop; - } - } - - /* Now find the block type */ - for (n = 0; n < sizeof(buf) - 1;) { - if ((c = unarmoured_read_char(stream, dearmour, errors, - readinfo, cbinfo, 0)) < 0) { - return 0; - } - if (c == '-') { - goto got_minus; - } - buf[n++] = c; - } - /* then I guess this wasn't a proper header */ - break; - -got_minus: - buf[n] = '\0'; - - /* Consume trailing '-' */ - for (count = 1; count < 5; ++count) { - if ((c = unarmoured_read_char(stream, dearmour, errors, - readinfo, cbinfo, 0)) < 0) { - return 0; - } - if (c != '-') { - /* wasn't a header after all */ - goto reloop; - } - } - - /* Consume final NL */ - if ((c = unarmoured_read_char(stream, dearmour, errors, readinfo, - cbinfo, 1)) < 0) { - return 0; - } - if (dearmour->allow_trailing_whitespace) { - if ((c = eat_whitespace(stream, c, dearmour, errors, - readinfo, cbinfo, 1)) < 0) { - return 0; - } - } - if (c != '\n') { - /* wasn't a header line after all */ - break; - } - - /* - * Now we've seen the header, scrub it from the - * buffer - */ - dearmour->unarmoredc = 0; - - /* - * But now we've seen a header line, then errors are - * EARLY_EOF - */ - if ((ret = parse_headers(stream, dearmour, errors, readinfo, - cbinfo)) <= 0) { - return -1; - } - - if (!set_lastseen_headerline(dearmour, buf, errors)) { - return -1; - } - - if (strcmp(buf, "BEGIN PGP SIGNED MESSAGE") == 0) { - dup_headers(&content.u.cleartext_head, - &dearmour->headers); - CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER, - cbinfo, - &content); - ret = process_dash_escaped(stream, dearmour, errors, - readinfo, cbinfo); - if (ret <= 0) { - return ret; - } - } else { - content.u.armour_header.type = buf; - content.u.armour_header.headers = - dearmour->headers; - (void) memset(&dearmour->headers, 0x0, - sizeof(dearmour->headers)); - CALLBACK(PGP_PTAG_CT_ARMOUR_HEADER, cbinfo, - &content); - base64(dearmour); - } - break; - - case BASE64: - first = 1; - while (length > 0) { - if (!dearmour->buffered) { - if (!dearmour->eof64) { - ret = decode64(stream, dearmour, - errors, readinfo, cbinfo); - if (ret <= 0) { - return ret; - } - } - if (!dearmour->buffered) { - if (!dearmour->eof64) { - (void) fprintf(stderr, -"armoured_data_reader: bad dearmour eof64\n"); - return 0; - } - if (first) { - dearmour->state = - AT_TRAILER_NAME; - goto reloop; - } - return -1; - } - } - if (!dearmour->buffered) { - (void) fprintf(stderr, - "armoured_data_reader: bad dearmour buffered\n"); - return 0; - } - *dest = dearmour->buffer[--dearmour->buffered]; - ++dest; - --length; - first = 0; - } - if (dearmour->eof64 && !dearmour->buffered) { - dearmour->state = AT_TRAILER_NAME; - } - break; - - case AT_TRAILER_NAME: - for (n = 0; n < sizeof(buf) - 1;) { - if ((c = read_char(stream, dearmour, errors, readinfo, - cbinfo, 0)) < 0) { - return -1; - } - if (c == '-') { - goto got_minus2; - } - buf[n++] = c; - } - /* then I guess this wasn't a proper trailer */ - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "%s", - "Bad ASCII armour trailer"); - break; - -got_minus2: - buf[n] = '\0'; - - if (!set_lastseen_headerline(dearmour, buf, errors)) { - return -1; - } - - /* Consume trailing '-' */ - for (count = 1; count < 5; ++count) { - if ((c = read_char(stream, dearmour, errors, readinfo, - cbinfo, 0)) < 0) { - return -1; - } - if (c != '-') { - /* wasn't a trailer after all */ - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", - "Bad ASCII armour trailer (2)"); - } - } - - /* Consume final NL */ - if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, - 1)) < 0) { - return -1; - } - if (dearmour->allow_trailing_whitespace) { - if ((c = eat_whitespace(stream, c, dearmour, errors, - readinfo, cbinfo, 1)) < 0) { - return 0; - } - } - if (c != '\n') { - /* wasn't a trailer line after all */ - PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, - "%s", "Bad ASCII armour trailer (3)"); - } - - if (strncmp(buf, "BEGIN ", 6) == 0) { - if (!set_lastseen_headerline(dearmour, buf, - errors)) { - return -1; - } - if ((ret = parse_headers(stream, dearmour, errors, - readinfo, cbinfo)) <= 0) { - return ret; - } - content.u.armour_header.type = buf; - content.u.armour_header.headers = - dearmour->headers; - (void) memset(&dearmour->headers, 0x0, - sizeof(dearmour->headers)); - CALLBACK(PGP_PTAG_CT_ARMOUR_HEADER, cbinfo, - &content); - base64(dearmour); - } else { - content.u.armour_trailer = buf; - CALLBACK(PGP_PTAG_CT_ARMOUR_TRAILER, cbinfo, - &content); - dearmour->state = OUTSIDE_BLOCK; - } - break; - } -reloop: - continue; - } - - return saved; -} - -static void -armoured_data_destroyer(pgp_reader_t *readinfo) -{ - free(pgp_reader_get_arg(readinfo)); -} - -/** - * \ingroup Core_Readers_Armour - * \brief Pushes dearmouring reader onto stack - * \param parse_info Usual structure containing information about to how to do the parse - * \sa pgp_reader_pop_dearmour() - */ -void -pgp_reader_push_dearmour(pgp_stream_t *parse_info) -/* - * This function originally had these params to cater for packets which - * didn't strictly match the RFC. The initial 0.5 release is only going to - * support strict checking. If it becomes desirable to support loose checking - * of armoured packets and these params are reinstated, parse_headers() must - * be fixed so that these flags work correctly. - * - * // Allow headers in armoured data that are not separated from the data by a - * blank line unsigned without_gap, - * - * // Allow no blank line at the start of armoured data unsigned no_gap, - * - * //Allow armoured data to have trailing whitespace where we strictly would not - * expect it unsigned trailing_whitespace - */ -{ - dearmour_t *dearmour; - - if ((dearmour = calloc(1, sizeof(*dearmour))) == NULL) { - (void) fprintf(stderr, "pgp_reader_push_dearmour: bad alloc\n"); - } else { - dearmour->seen_nl = 1; - /* - dearmour->allow_headers_without_gap=without_gap; - dearmour->allow_no_gap=no_gap; - dearmour->allow_trailing_whitespace=trailing_whitespace; - */ - dearmour->expect_sig = 0; - dearmour->got_sig = 0; - - pgp_reader_push(parse_info, armoured_data_reader, - armoured_data_destroyer, dearmour); - } -} - -/** - * \ingroup Core_Readers_Armour - * \brief Pops dearmour reader from stock - * \param stream - * \sa pgp_reader_push_dearmour() - */ -void -pgp_reader_pop_dearmour(pgp_stream_t *stream) -{ - dearmour_t *dearmour; - - dearmour = pgp_reader_get_arg(pgp_readinfo(stream)); - free(dearmour); - pgp_reader_pop(stream); -} - -/**************************************************************************/ - -/* this is actually used for *decrypting* */ -typedef struct { - uint8_t decrypted[1024 * 15]; - size_t c; - size_t off; - pgp_crypt_t *decrypt; - pgp_region_t *region; - // unsigned prevplain:1; -} encrypted_t; - -static int -encrypted_data_reader(pgp_stream_t *stream, void *dest, - size_t length, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - encrypted_t *encrypted; - char *cdest; - int saved; - - encrypted = pgp_reader_get_arg(readinfo); - saved = (int)length; - -#if 0 - /* - * V3 MPIs have the count plain and the cipher is reset after each - * count - */ - if (encrypted->prevplain && !readinfo->parent->reading_mpi_len) { - if (!readinfo->parent->reading_v3_secret) { - (void) fprintf(stderr, - "encrypted_data_reader: bad v3 secret\n"); - return -1; - } - encrypted->decrypt->decrypt_resync(encrypted->decrypt); - encrypted->prevplain = 0; - } else if (readinfo->parent->reading_v3_secret && - readinfo->parent->reading_mpi_len) { - encrypted->prevplain = 1; - } -#endif - - while (length > 0) { - if (encrypted->c) { - unsigned n; - - /* - * if we are reading v3 we should never read - * more than we're asked for - if (length < encrypted->c && - (readinfo->parent->reading_v3_secret || - readinfo->parent->exact_read)) { - (void) fprintf(stderr, - "encrypted_data_reader: bad v3 read\n"); - return 0; - } - */ - n = (int)MIN(length, encrypted->c); - (void) memcpy(dest, - encrypted->decrypted + encrypted->off, n); - encrypted->c -= n; - encrypted->off += n; - length -= n; - cdest = dest; - cdest += n; - dest = cdest; - } else { - unsigned n = encrypted->region->length; - uint8_t buffer[1024]; - - if (!n) { - return -1; - } - if (!encrypted->region->indeterminate) { - n -= encrypted->region->readc; - if (n == 0) { - return (int)(saved - length); - } - if (n > sizeof(buffer)) { - n = sizeof(buffer); - } - } else { - n = sizeof(buffer); - } - - /* - * we can only read as much as we're asked for - * in v3 keys because they're partially - * unencrypted! - if ((readinfo->parent->reading_v3_secret || - readinfo->parent->exact_read) && n > length) { - n = (unsigned)length; - } - */ - - if (!pgp_stacked_limited_read(stream, buffer, n, - encrypted->region, errors, readinfo, cbinfo)) { - return -1; - } - //if (!readinfo->parent->reading_v3_secret || - // !readinfo->parent->reading_mpi_len) { - encrypted->c = - pgp_decrypt_se_ip(encrypted->decrypt, - encrypted->decrypted, buffer, n); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "encrypted", buffer, 16); - hexdump(stderr, "decrypted", encrypted->decrypted, 16); - } - //} else { - // (void) memcpy( - //&encrypted->decrypted[encrypted->off], buffer, n); - //encrypted->c = n; - //} - - if (encrypted->c == 0) { - (void) fprintf(stderr, - "encrypted_data_reader: 0 decrypted count\n"); - return 0; - } - - encrypted->off = 0; - } - } - - return saved; -} - -static void -encrypted_data_destroyer(pgp_reader_t *readinfo) -{ - free(pgp_reader_get_arg(readinfo)); -} - -/** - * \ingroup Core_Readers_SE - * \brief Pushes decryption reader onto stack - * \sa pgp_reader_pop_decrypt() - */ -void -pgp_reader_push_decrypt(pgp_stream_t *stream, pgp_crypt_t *decrypt, - pgp_region_t *region) -{ - encrypted_t *encrypted; - - if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) { - (void) fprintf(stderr, "pgp_reader_push_decrypted: bad alloc\n"); - } else { - encrypted->decrypt = decrypt; - encrypted->region = region; - pgp_decrypt_init(encrypted->decrypt); - pgp_reader_push(stream, encrypted_data_reader, - encrypted_data_destroyer, encrypted); - } -} - -/** - * \ingroup Core_Readers_Encrypted - * \brief Pops decryption reader from stack - * \sa pgp_reader_push_decrypt() - */ -void -pgp_reader_pop_decrypt(pgp_stream_t *stream) -{ - encrypted_t *encrypted; - - encrypted = pgp_reader_get_arg(pgp_readinfo(stream)); - encrypted->decrypt->decrypt_finish(encrypted->decrypt); - free(encrypted); - pgp_reader_pop(stream); -} - -/**************************************************************************/ - -typedef struct { - /* boolean: 0 once we've done the preamble/MDC checks */ - /* and are reading from the plaintext */ - int passed_checks; - uint8_t *plaintext; - size_t plaintext_available; - size_t plaintext_offset; - pgp_region_t *region; - pgp_crypt_t *decrypt; -} decrypt_se_ip_t; - -/* - Gets entire SE_IP data packet. - Verifies leading preamble - Verifies trailing MDC packet - Then passes up plaintext as requested -*/ -static int -se_ip_data_reader(pgp_stream_t *stream, void *dest_, - size_t len, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - decrypt_se_ip_t *se_ip; - pgp_region_t decrypted_region; - unsigned n = 0; - - se_ip = pgp_reader_get_arg(readinfo); - if (!se_ip->passed_checks) { - uint8_t *buf = NULL; - uint8_t hashed[PGP_SHA1_HASH_SIZE]; - uint8_t *preamble; - uint8_t *plaintext; - uint8_t *mdc; - uint8_t *mdc_hash; - pgp_hash_t hash; - size_t b; - size_t sz_preamble; - size_t sz_mdc_hash; - size_t sz_mdc; - size_t sz_plaintext; - - pgp_hash_any(&hash, PGP_HASH_SHA1); - if (!hash.init(&hash)) { - (void) fprintf(stderr, - "se_ip_data_reader: can't init hash\n"); - return -1; - } - - pgp_init_subregion(&decrypted_region, NULL); - decrypted_region.length = - se_ip->region->length - se_ip->region->readc; - if ((buf = calloc(1, decrypted_region.length)) == NULL) { - (void) fprintf(stderr, "se_ip_data_reader: bad alloc\n"); - return -1; - } - - /* read entire SE IP packet */ - if (!pgp_stacked_limited_read(stream, buf, decrypted_region.length, - &decrypted_region, errors, readinfo, cbinfo)) { - free(buf); - return -1; - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "SE IP packet", buf, decrypted_region.length); - } - /* verify leading preamble */ - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "preamble", buf, se_ip->decrypt->blocksize); - } - b = se_ip->decrypt->blocksize; - if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) { - fprintf(stderr, - "Bad symmetric decrypt (%02x%02x vs %02x%02x)\n", - buf[b - 2], buf[b - 1], buf[b], buf[b + 1]); - PGP_ERROR_1(errors, PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT, - "%s", "Bad symmetric decrypt when parsing SE IP" - " packet"); - free(buf); - return -1; - } - /* Verify trailing MDC hash */ - - sz_preamble = se_ip->decrypt->blocksize + 2; - sz_mdc_hash = PGP_SHA1_HASH_SIZE; - sz_mdc = 1 + 1 + sz_mdc_hash; - sz_plaintext = (decrypted_region.length - sz_preamble) - sz_mdc; - - preamble = buf; - plaintext = buf + sz_preamble; - mdc = plaintext + sz_plaintext; - mdc_hash = mdc + 2; - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "plaintext", plaintext, sz_plaintext); - hexdump(stderr, "mdc", mdc, sz_mdc); - } - pgp_calc_mdc_hash(preamble, sz_preamble, plaintext, - (unsigned)sz_plaintext, hashed); - - if (memcmp(mdc_hash, hashed, PGP_SHA1_HASH_SIZE) != 0) { - PGP_ERROR_1(errors, PGP_E_V_BAD_HASH, "%s", - "Bad hash in MDC packet"); - free(buf); - return 0; - } - /* all done with the checks */ - /* now can start reading from the plaintext */ - if (se_ip->plaintext) { - (void) fprintf(stderr, - "se_ip_data_reader: bad plaintext\n"); - return 0; - } - if ((se_ip->plaintext = calloc(1, sz_plaintext)) == NULL) { - (void) fprintf(stderr, - "se_ip_data_reader: bad alloc\n"); - return 0; - } - memcpy(se_ip->plaintext, plaintext, sz_plaintext); - se_ip->plaintext_available = sz_plaintext; - - se_ip->passed_checks = 1; - - free(buf); - } - n = (unsigned)len; - if (n > se_ip->plaintext_available) { - n = (unsigned)se_ip->plaintext_available; - } - - memcpy(dest_, se_ip->plaintext + se_ip->plaintext_offset, n); - se_ip->plaintext_available -= n; - se_ip->plaintext_offset += n; - /* len -= n; - not used at all, for info only */ - - return n; -} - -static void -se_ip_data_destroyer(pgp_reader_t *readinfo) -{ - decrypt_se_ip_t *se_ip; - - se_ip = pgp_reader_get_arg(readinfo); - free(se_ip->plaintext); - free(se_ip); -} - -/** - \ingroup Internal_Readers_SEIP -*/ -void -pgp_reader_push_se_ip_data(pgp_stream_t *stream, pgp_crypt_t *decrypt, - pgp_region_t * region) -{ - decrypt_se_ip_t *se_ip; - - if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) { - (void) fprintf(stderr, "pgp_reader_push_se_ip_data: bad alloc\n"); - } else { - se_ip->region = region; - se_ip->decrypt = decrypt; - pgp_reader_push(stream, se_ip_data_reader, se_ip_data_destroyer, - se_ip); - } -} - -/** - \ingroup Internal_Readers_SEIP - */ -void -pgp_reader_pop_se_ip_data(pgp_stream_t *stream) -{ - /* - * decrypt_se_ip_t - * *se_ip=pgp_reader_get_arg(pgp_readinfo(stream)); - */ - /* free(se_ip); */ - pgp_reader_pop(stream); -} - -/**************************************************************************/ - -/** Arguments for reader_fd - */ -typedef struct mmap_reader_t { - void *mem; /* memory mapped file */ - uint64_t size; /* size of file */ - uint64_t offset; /* current offset in file */ - int fd; /* file descriptor */ -} mmap_reader_t; - - -/** - * \ingroup Core_Readers - * - * pgp_reader_fd() attempts to read up to "plength" bytes from the file - * descriptor in "parse_info" into the buffer starting at "dest" using the - * rules contained in "flags" - * - * \param dest Pointer to previously allocated buffer - * \param plength Number of bytes to try to read - * \param flags Rules about reading to use - * \param readinfo Reader info - * \param cbinfo Callback info - * - * \return n Number of bytes read - * - * PGP_R_EARLY_EOF and PGP_R_ERROR push errors on the stack - */ -static int -fd_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - mmap_reader_t *reader; - int n; - - __PGP_USED(cbinfo); - reader = pgp_reader_get_arg(readinfo); - - n = (int)read(reader->fd, dest, length); - - if (n == 0) { - return 0; - } - if (n < 0) { - PGP_SYSTEM_ERROR_1(errors, PGP_E_R_READ_FAILED, "read", - "file descriptor %d", reader->fd); - return -1; - } - return n; -} - -static void -reader_fd_destroyer(pgp_reader_t *readinfo) -{ - free(pgp_reader_get_arg(readinfo)); -} - -/** - \ingroup Core_Readers_First - \brief Starts stack with file reader -*/ - -void -pgp_reader_set_fd(pgp_stream_t *stream, int fd) -{ - mmap_reader_t *reader; - - if ((reader = calloc(1, sizeof(*reader))) == NULL) { - (void) fprintf(stderr, "pgp_reader_set_fd: bad alloc\n"); - } else { - reader->fd = fd; - pgp_reader_set(stream, fd_reader, reader_fd_destroyer, reader); - } -} - -/**************************************************************************/ - -typedef struct { - const uint8_t *buffer; - size_t length; - size_t offset; -} reader_mem_t; - -static int -mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - reader_mem_t *reader = pgp_reader_get_arg(readinfo); - unsigned n; - - __PGP_USED(cbinfo); - __PGP_USED(errors); - - if (reader->offset + length > reader->length) { - n = (unsigned)(reader->length - reader->offset); - } else { - n = (unsigned)length; - } - if (n == (unsigned)0) { - return 0; - } - memcpy(dest, reader->buffer + reader->offset, n); - reader->offset += n; - - return n; -} - -static void -mem_destroyer(pgp_reader_t *readinfo) -{ - free(pgp_reader_get_arg(readinfo)); -} - -/** - \ingroup Core_Readers_First - \brief Starts stack with memory reader -*/ - -void -pgp_reader_set_memory(pgp_stream_t *stream, const void *buffer, - size_t length) -{ - reader_mem_t *mem; - - if ((mem = calloc(1, sizeof(*mem))) == NULL) { - (void) fprintf(stderr, "pgp_reader_set_memory: bad alloc\n"); - } else { - mem->buffer = buffer; - mem->length = length; - mem->offset = 0; - pgp_reader_set(stream, mem_reader, mem_destroyer, mem); - } -} - -/**************************************************************************/ - -/** - \ingroup Core_Writers - \brief Create and initialise output and mem; Set for writing to mem - \param output Address where new output pointer will be set - \param mem Address when new mem pointer will be set - \param bufsz Initial buffer size (will automatically be increased when necessary) - \note It is the caller's responsiblity to free output and mem. - \sa pgp_teardown_memory_write() -*/ -void -pgp_setup_memory_write(pgp_output_t **output, pgp_memory_t **mem, size_t bufsz) -{ - /* - * initialise needed structures for writing to memory - */ - - *output = pgp_output_new(); - *mem = pgp_memory_new(); - - pgp_memory_init(*mem, bufsz); - - pgp_writer_set_memory(*output, *mem); -} - -/** - \ingroup Core_Writers - \brief Closes writer and frees output and mem - \param output - \param mem - \sa pgp_setup_memory_write() -*/ -void -pgp_teardown_memory_write(pgp_output_t *output, pgp_memory_t *mem) -{ - pgp_writer_close(output);/* new */ - pgp_output_delete(output); - pgp_memory_free(mem); -} - -/** - \ingroup Core_Readers - \brief Create parse_info and sets to read from memory - \param stream Address where new parse_info will be set - \param mem Memory to read from - \param arg Reader-specific arg - \param callback Callback to use with reader - \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification) - \note It is the caller's responsiblity to free parse_info - \sa pgp_teardown_memory_read() -*/ -void -pgp_setup_memory_read(pgp_io_t *io, - pgp_stream_t **stream, - pgp_memory_t *mem, - void *vp, - pgp_cb_ret_t callback(const pgp_packet_t *, - pgp_cbdata_t *), - unsigned accumulate) -{ - *stream = pgp_new(sizeof(**stream)); - (*stream)->io = (*stream)->cbinfo.io = io; - pgp_set_callback(*stream, callback, vp); - pgp_reader_set_memory(*stream, - pgp_mem_data(mem), - pgp_mem_len(mem)); - if (accumulate) { - (*stream)->readinfo.accumulate = 1; - } -} - -/** - \ingroup Core_Readers - \brief Frees stream and mem - \param stream - \param mem - \sa pgp_setup_memory_read() -*/ -void -pgp_teardown_memory_read(pgp_stream_t *stream, pgp_memory_t *mem) -{ - pgp_stream_delete(stream); - pgp_memory_free(mem); -} - -/** - \ingroup Core_Writers - \brief Create and initialise output and mem; Set for writing to file - \param output Address where new output pointer will be set - \param filename File to write to - \param allow_overwrite Allows file to be overwritten, if set. - \return Newly-opened file descriptor - \note It is the caller's responsiblity to free output and to close fd. - \sa pgp_teardown_file_write() -*/ -#if 0 ////// -int -pgp_setup_file_write(pgp_output_t **output, const char *filename, - unsigned allow_overwrite) -{ - int fd = 0; - int flags = 0; - - /* - * initialise needed structures for writing to file - */ - if (filename == NULL) { - /* write to stdout */ - fd = STDOUT_FILENO; - } else { - flags = O_WRONLY | O_CREAT; - if (allow_overwrite) - flags |= O_TRUNC; - else - flags |= O_EXCL; -#ifdef O_BINARY - flags |= O_BINARY; -#endif - fd = open(filename, flags, 0600); - if (fd < 0) { - perror(filename); - return fd; - } - } - *output = pgp_output_new(); - pgp_writer_set_fd(*output, fd); - return fd; -} -#endif ////// - -/** - \ingroup Core_Writers - \brief Closes writer, frees info, closes fd - \param output - \param fd -*/ -#if 0 ////// -void -pgp_teardown_file_write(pgp_output_t *output, int fd) -{ - pgp_writer_close(output); - close(fd); - pgp_output_delete(output); -} -#endif ////// - -/** - \ingroup Core_Writers - \brief As pgp_setup_file_write, but appends to file -*/ -#if 0 ////// -int -pgp_setup_file_append(pgp_output_t **output, const char *filename) -{ - int fd; - - /* - * initialise needed structures for writing to file - */ -#ifdef O_BINARY - fd = open(filename, O_WRONLY | O_APPEND | O_BINARY, 0600); -#else - fd = open(filename, O_WRONLY | O_APPEND, 0600); -#endif - if (fd >= 0) { - *output = pgp_output_new(); - pgp_writer_set_fd(*output, fd); - } - return fd; -} -#endif ////// - -/** - \ingroup Core_Writers - \brief As pgp_teardown_file_write() -*/ -#if 0 ////// -void -pgp_teardown_file_append(pgp_output_t *output, int fd) -{ - pgp_teardown_file_write(output, fd); -} -#endif ////// - -/** - \ingroup Core_Readers - \brief Creates parse_info, opens file, and sets to read from file - \param stream Address where new parse_info will be set - \param filename Name of file to read - \param vp Reader-specific arg - \param callback Callback to use when reading - \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification) - \note It is the caller's responsiblity to free parse_info and to close fd - \sa pgp_teardown_file_read() -*/ -#if 0 ////// -int -pgp_setup_file_read(pgp_io_t *io, - pgp_stream_t **stream, - const char *filename, - void *vp, - pgp_cb_ret_t callback(const pgp_packet_t *, - pgp_cbdata_t *), - unsigned accumulate) -{ - int fd; - -#ifdef O_BINARY - fd = open(filename, O_RDONLY | O_BINARY); -#else - fd = open(filename, O_RDONLY); -#endif - if (fd < 0) { - (void) fprintf(io->errs, "can't open \"%s\"\n", filename); - return fd; - } - *stream = pgp_new(sizeof(**stream)); - (*stream)->io = (*stream)->cbinfo.io = io; - pgp_set_callback(*stream, callback, vp); -#ifdef USE_MMAP_FOR_FILES - pgp_reader_set_mmap(*stream, fd); -#else - pgp_reader_set_fd(*stream, fd); -#endif - if (accumulate) { - (*stream)->readinfo.accumulate = 1; - } - return fd; -} -#endif ////// - -/** - \ingroup Core_Readers - \brief Frees stream and closes fd - \param stream - \param fd - \sa pgp_setup_file_read() -*/ -#if 0 ////// -void -pgp_teardown_file_read(pgp_stream_t *stream, int fd) -{ - close(fd); - pgp_stream_delete(stream); -} -#endif ////// - -pgp_cb_ret_t -pgp_litdata_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - - if (pgp_get_debug_level(__FILE__)) { - printf("pgp_litdata_cb: "); - //pgp_print_packet(&cbinfo->printstate, pkt); - } - /* Read data from packet into static buffer */ - switch (pkt->tag) { - case PGP_PTAG_CT_LITDATA_BODY: - /* if writer enabled, use it */ - if (cbinfo->output) { - if (pgp_get_debug_level(__FILE__)) { - printf("pgp_litdata_cb: length is %u\n", - content->litdata_body.length); - } - pgp_write(cbinfo->output, - content->litdata_body.data, - content->litdata_body.length); - } - break; - - case PGP_PTAG_CT_LITDATA_HEADER: - /* ignore */ - break; - - default: - break; - } - - return PGP_RELEASE_MEMORY; -} - -pgp_cb_ret_t -pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - unsigned from; - pgp_io_t *io; - - io = cbinfo->io; - if (pgp_get_debug_level(__FILE__)) { - //pgp_print_packet(&cbinfo->printstate, pkt); - } - /* Read data from packet into static buffer */ - switch (pkt->tag) { - case PGP_PTAG_CT_PK_SESSION_KEY: - if (pgp_get_debug_level(__FILE__)) { - printf("PGP_PTAG_CT_PK_SESSION_KEY\n"); - } - if (!cbinfo->cryptinfo.secring) { - (void) fprintf(io->errs, - "pgp_pk_sesskey_cb: bad keyring\n"); - return (pgp_cb_ret_t)0; - } - from = 0; - cbinfo->cryptinfo.keydata = - pgp_getkeybyid(io, cbinfo->cryptinfo.secring, - content->pk_sesskey.key_id, &from, NULL, NULL, - 0, 0); /* accepts revoked and expired */ - if (!cbinfo->cryptinfo.keydata) { - break; - } - break; - - default: - break; - } - - return PGP_RELEASE_MEMORY; -} - -/** - \ingroup Core_Callbacks - -\brief Callback to get secret key, decrypting if necessary. - -@verbatim - This callback does the following: - * finds the session key in the keyring - * gets a passphrase if required - * decrypts the secret key, if necessary - * sets the seckey in the content struct -@endverbatim -*/ - -pgp_cb_ret_t -pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - pgp_seckey_t *secret; - // const pgp_key_t *pubkey; - //const pgp_key_t *keypair; - unsigned from; - pgp_io_t *io; - //int i; - - pgp_cryptinfo_t *cryptinfo = &cbinfo->cryptinfo; - key_id_t *key_id; - - io = cbinfo->io; - if (pgp_get_debug_level(__FILE__)) { - //pgp_print_packet(&cbinfo->printstate, pkt); - } - switch (pkt->tag) { - case PGP_GET_SECKEY: - /* print key from pubring */ - // from = 0; - // pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring, - // content->get_seckey.pk_sesskey->key_id, - // &from, NULL); - // /* validate key from secring */ - - EXPAND_ARRAY(cryptinfo, recipients_key_ids); - key_id = &cryptinfo->recipients_key_idss[cryptinfo->recipients_key_idsc++]; - memcpy(key_id, content->get_seckey.pk_sesskey->key_id, sizeof(key_id_t)); - - from = 0; - cbinfo->cryptinfo.keydata = - pgp_getkeybyid(io, cbinfo->cryptinfo.secring, - content->get_seckey.pk_sesskey->key_id, - &from, NULL, &secret, 0, 0); - if (!cbinfo->cryptinfo.keydata || - !secret || - !pgp_is_key_secret(cbinfo->cryptinfo.keydata)) { - return (pgp_cb_ret_t)0; - } - - // FIXME : support encrypted seckeys again - // keypair = cbinfo->cryptinfo.keydata; - // if (pubkey == NULL) { - // pubkey = keypair; - // } - // secret = NULL; - // cbinfo->gotpass = 0; - // for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) { - // /* print out the user id */ - // pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey, - // "signature ", &pubkey->key.pubkey, 0); - // /* now decrypt key */ - // pgp_decrypt_seckey(keypair, cbinfo->passfp); - // if (secret != NULL) { - // break; - // } - // (void) fprintf(io->errs, "Bad passphrase\n"); - // } - // if (secret == NULL) { - // (void) fprintf(io->errs, "Exhausted passphrase attempts\n"); - // return (pgp_cb_ret_t)PGP_RELEASE_MEMORY; - // } - - cbinfo->gotpass = 1; - *content->get_seckey.seckey = secret; - break; - - default: - break; - } - - return PGP_RELEASE_MEMORY; -} - -#if 0 ////// -unsigned -pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state) -{ - return stream->readinfo.accumulate = state; -} -#endif ////// - -/**************************************************************************/ - -static int -hash_reader(pgp_stream_t *stream, void *dest, - size_t length, - pgp_error_t **errors, - pgp_reader_t *readinfo, - pgp_cbdata_t *cbinfo) -{ - pgp_hash_t *hash = pgp_reader_get_arg(readinfo); - int r; - - r = pgp_stacked_read(stream, dest, length, errors, readinfo, cbinfo); - if (r <= 0) { - return r; - } - hash->add(hash, dest, (unsigned)r); - return r; -} - -/** - \ingroup Internal_Readers_Hash - \brief Push hashed data reader on stack -*/ -void -pgp_reader_push_hash(pgp_stream_t *stream, pgp_hash_t *hash) -{ - if (!hash->init(hash)) { - (void) fprintf(stderr, "pgp_reader_push_hash: can't init hash\n"); - /* just continue and die */ - /* XXX - agc - no way to return failure */ - } - pgp_reader_push(stream, hash_reader, NULL, hash); -} - -/** - \ingroup Internal_Readers_Hash - \brief Pop hashed data reader from stack -*/ -void -pgp_reader_pop_hash(pgp_stream_t *stream) -{ - pgp_reader_pop(stream); -} - -/* read memory from the previously mmap-ed file */ -static int -mmap_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, - pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo) -{ - mmap_reader_t *mem = pgp_reader_get_arg(readinfo); - unsigned n; - char *cmem = mem->mem; - - __PGP_USED(errors); - __PGP_USED(cbinfo); - - n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset)); - if (n > 0) { - (void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n); - mem->offset += n; - } - return (int)n; -} - -/* tear down the mmap, close the fd */ -static void -mmap_destroyer(pgp_reader_t *readinfo) -{ - mmap_reader_t *mem = pgp_reader_get_arg(readinfo); - - (void) munmap(mem->mem, (unsigned)mem->size); - (void) close(mem->fd); - free(pgp_reader_get_arg(readinfo)); -} - -/* set up the file to use mmap-ed memory if available, file IO otherwise */ -void -pgp_reader_set_mmap(pgp_stream_t *stream, int fd) -{ - mmap_reader_t *mem; - struct stat st; - - if (fstat(fd, &st) != 0) { - (void) fprintf(stderr, "pgp_reader_set_mmap: can't fstat\n"); - } else if ((mem = calloc(1, sizeof(*mem))) == NULL) { - (void) fprintf(stderr, "pgp_reader_set_mmap: bad alloc\n"); - } else { - mem->size = (uint64_t)st.st_size; - mem->offset = 0; - mem->fd = fd; - mem->mem = mmap(NULL, (size_t)st.st_size, PROT_READ, - MAP_PRIVATE | MAP_FILE, fd, 0); - if (mem->mem == MAP_FAILED) { - pgp_reader_set(stream, fd_reader, reader_fd_destroyer, - mem); - } else { - pgp_reader_set(stream, mmap_reader, mmap_destroyer, - mem); - } - } -} diff --git a/netpgp/signature.c b/netpgp/signature.c deleted file mode 100644 index 69b98ca5e7a612773d16bfebc1e5ca715039e428..0000000000000000000000000000000000000000 --- a/netpgp/signature.c +++ /dev/null @@ -1,1384 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/param.h> - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_OPENSSL_DSA_H -#include <openssl/dsa.h> -#endif - -#include "netpgp/signature.h" -#include "netpgp/crypto.h" -#include "netpgp/create.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/readerwriter.h" -#include "netpgp/validate.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/netpgpdigest.h" - - -/** - \ingroup Core_Signature - Creates new pgp_create_sig_t - \return new pgp_create_sig_t - \note It is the caller's responsibility to call pgp_create_sig_delete() - \sa pgp_create_sig_delete() -*/ -pgp_create_sig_t * -pgp_create_sig_new(void) -{ - return calloc(1, sizeof(pgp_create_sig_t)); -} - -/** - \ingroup Core_Signature - Free signature and memory associated with it - \param sig struct to free - \sa pgp_create_sig_new() -*/ -void -pgp_create_sig_delete(pgp_create_sig_t *sig) -{ - pgp_output_delete(sig->output); - sig->output = NULL; - free(sig); -} - -#if 0 -void -pgp_dump_sig(pgp_sig_t *sig) -{ -} -#endif - -static uint8_t prefix_md5[] = { - 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 -}; - -static uint8_t prefix_sha1[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, - 0x1A, 0x05, 0x00, 0x04, 0x14 -}; - -static uint8_t prefix_sha256[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 -}; - -static uint8_t prefix_sha512[] = { - 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, - 0x00, 0x04, 0x40 -}; - -/* XXX: both this and verify would be clearer if the signature were */ -/* treated as an MPI. */ -static int -rsa_sign(pgp_hash_t *hash, - const pgp_rsa_pubkey_t *pubrsa, - const pgp_rsa_seckey_t *secrsa, - pgp_output_t *out) -{ - unsigned prefixsize; - unsigned expected; - unsigned hashsize; - unsigned keysize; - unsigned n; - unsigned t; - uint8_t hashbuf[NETPGP_BUFSIZ]; - uint8_t sigbuf[NETPGP_BUFSIZ]; - uint8_t *prefix; - BIGNUM *bn; - - if (strcmp(hash->name, "SHA1") == 0) { - hashsize = PGP_SHA1_HASH_SIZE + sizeof(prefix_sha1); - prefix = prefix_sha1; - prefixsize = sizeof(prefix_sha1); - expected = PGP_SHA1_HASH_SIZE; - } else if (strcmp(hash->name, "SHA256") == 0) { - hashsize = PGP_SHA256_HASH_SIZE + sizeof(prefix_sha256); - prefix = prefix_sha256; - prefixsize = sizeof(prefix_sha256); - expected = PGP_SHA256_HASH_SIZE; - } else { - hashsize = PGP_SHA512_HASH_SIZE + sizeof(prefix_sha512); - prefix = prefix_sha512; - prefixsize = sizeof(prefix_sha512); - expected = PGP_SHA512_HASH_SIZE; - } - keysize = (BN_num_bits(pubrsa->n) + 7) / 8; - if (keysize > sizeof(hashbuf)) { - (void) fprintf(stderr, "rsa_sign: keysize too big\n"); - return 0; - } - if (10 + hashsize > keysize) { - (void) fprintf(stderr, "rsa_sign: hashsize too big\n"); - return 0; - } - - hashbuf[0] = 0; - hashbuf[1] = 1; - if (pgp_get_debug_level(__FILE__)) { - printf("rsa_sign: PS is %d\n", keysize - hashsize - 1 - 2); - } - for (n = 2; n < keysize - hashsize - 1; ++n) { - hashbuf[n] = 0xff; - } - hashbuf[n++] = 0; - - (void) memcpy(&hashbuf[n], prefix, prefixsize); - n += prefixsize; - if ((t = hash->finish(hash, &hashbuf[n])) != expected) { - (void) fprintf(stderr, "rsa_sign: short %s hash\n", hash->name); - return 0; - } - - pgp_write(out, &hashbuf[n], 2); - - n += t; - if (n != keysize) { - (void) fprintf(stderr, "rsa_sign: n != keysize\n"); - return 0; - } - - t = pgp_rsa_private_encrypt(sigbuf, hashbuf, keysize, secrsa, pubrsa); - bn = BN_bin2bn(sigbuf, (int)t, NULL); - pgp_write_mpi(out, bn); - BN_free(bn); - return 1; -} - -static int -dsa_sign(pgp_hash_t *hash, - const pgp_dsa_pubkey_t *dsa, - const pgp_dsa_seckey_t *sdsa, - pgp_output_t *output) -{ - unsigned hashsize; - unsigned t; - uint8_t hashbuf[NETPGP_BUFSIZ]; - pgp_dsa_sig_t *pgpdsasig; - - /* hashsize must be "equal in size to the number of bits of q, */ - /* the group generated by the DSA key's generator value */ - /* 160/8 = 20 */ - - hashsize = 20; - - /* finalise hash */ - t = hash->finish(hash, &hashbuf[0]); - if (t != 20) { - (void) fprintf(stderr, "dsa_sign: hashfinish not 20\n"); - return 0; - } - - pgp_write(output, &hashbuf[0], 2); - - /* write signature to buf */ - pgpdsasig = pgp_dsa_sign(hashbuf, hashsize, sdsa, dsa); - - if(pgpdsasig == NULL) - return 0; - - /* convert and write the sig out to memory */ - pgp_write_mpi(output, pgpdsasig->r); - pgp_write_mpi(output, pgpdsasig->s); - - BN_free(pgpdsasig->r); - BN_free(pgpdsasig->s); - free(pgpdsasig); - return 1; -} - -static unsigned -rsa_verify(pgp_hash_alg_t type, - const uint8_t *hash, - size_t hash_length, - const pgp_rsa_sig_t *sig, - const pgp_rsa_pubkey_t *pubrsa) -{ - const uint8_t *prefix; - unsigned n; - unsigned keysize; - unsigned plen; - unsigned debug_len_decrypted; - uint8_t sigbuf[NETPGP_BUFSIZ]; - uint8_t hashbuf_from_sig[NETPGP_BUFSIZ]; - - keysize = BN_num_bytes(pubrsa->n); - /* RSA key can't be bigger than 65535 bits, so... */ - if (keysize > sizeof(hashbuf_from_sig)) { - (void) fprintf(stderr, "rsa_verify: keysize too big\n"); - return 0; - } - if ((unsigned) BN_num_bits(sig->sig) > 8 * sizeof(sigbuf)) { - (void) fprintf(stderr, "rsa_verify: BN_numbits too big\n"); - return 0; - } - BN_bn2bin(sig->sig, sigbuf); - - n = pgp_rsa_public_decrypt(hashbuf_from_sig, sigbuf, - (unsigned)(BN_num_bits(sig->sig) + 7) / 8, pubrsa); - debug_len_decrypted = n; - - if (n != keysize) { - /* obviously, this includes error returns */ - return 0; - } - - /* XXX: why is there a leading 0? The first byte should be 1... */ - /* XXX: because the decrypt should use keysize and not sigsize? */ - if (hashbuf_from_sig[0] != 0 || hashbuf_from_sig[1] != 1) { - return 0; - } - - switch (type) { - case PGP_HASH_MD5: - prefix = prefix_md5; - plen = sizeof(prefix_md5); - break; - case PGP_HASH_SHA1: - prefix = prefix_sha1; - plen = sizeof(prefix_sha1); - break; - case PGP_HASH_SHA256: - prefix = prefix_sha256; - plen = sizeof(prefix_sha256); - break; - case PGP_HASH_SHA512: - prefix = prefix_sha512; - plen = sizeof(prefix_sha512); - break; - default: - (void) fprintf(stderr, "Unknown hash algorithm: %d\n", type); - return 0; - } - - if (keysize - plen - hash_length < 10) { - return 0; - } - - for (n = 2; n < keysize - plen - hash_length - 1; ++n) { - if (hashbuf_from_sig[n] != 0xff) { - return 0; - } - } - - if (hashbuf_from_sig[n++] != 0) { - return 0; - } - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sig hashbuf", hashbuf_from_sig, debug_len_decrypted); - hexdump(stderr, "prefix", prefix, plen); - hexdump(stderr, "sig hash", &hashbuf_from_sig[n + plen], hash_length); - hexdump(stderr, "input hash", hash, hash_length); - } - return (memcmp(&hashbuf_from_sig[n], prefix, plen) == 0 && - memcmp(&hashbuf_from_sig[n + plen], hash, hash_length) == 0); -} - -static void -hash_add_key(pgp_hash_t *hash, const pgp_pubkey_t *key) -{ - pgp_memory_t *mem = pgp_memory_new(); - const unsigned dontmakepacket = 0; - size_t len; - - pgp_build_pubkey(mem, key, dontmakepacket); - len = pgp_mem_len(mem); - pgp_hash_add_int(hash, 0x99, 1); - pgp_hash_add_int(hash, (unsigned)len, 2); - hash->add(hash, pgp_mem_data(mem), (unsigned)len); - - pgp_memory_free(mem); -} - -static void -initialise_hash(pgp_hash_t *hash, const pgp_sig_t *sig) -{ - pgp_hash_any(hash, sig->info.hash_alg); - if (!hash->init(hash)) { - (void) fprintf(stderr, - "initialise_hash: bad hash init\n"); - /* just continue and die */ - /* XXX - agc - no way to return failure */ - } -} - -static void -init_key_sig(pgp_hash_t *hash, const pgp_sig_t *sig, - const pgp_pubkey_t *key) -{ - initialise_hash(hash, sig); - hash_add_key(hash, key); -} - -static void -hash_add_trailer(pgp_hash_t *hash, const pgp_sig_t *sig) -{ - if (sig->info.version == PGP_V4) { - if (sig->info.v4_hashlen) { - hash->add(hash, sig->info.v4_hashed, - (unsigned)sig->info.v4_hashlen); - } - pgp_hash_add_int(hash, (unsigned)sig->info.version, 1); - pgp_hash_add_int(hash, 0xff, 1); - pgp_hash_add_int(hash, (unsigned)sig->info.v4_hashlen, 4); - } else { - pgp_hash_add_int(hash, (unsigned)sig->info.type, 1); - pgp_hash_add_int(hash, (unsigned)sig->info.birthtime, 4); - } -} - -/** - \ingroup Core_Signature - \brief Checks a signature - \param hash Signature Hash to be checked - \param length Signature Length - \param sig The Signature to be checked - \param signer The signer's public key - \return 1 if good; else 0 -*/ -unsigned -pgp_check_sig(const uint8_t *hash, unsigned length, - const pgp_sig_t * sig, - const pgp_pubkey_t * signer) -{ - unsigned ret; - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stdout, "hash", hash, length); - } - - switch (sig->info.key_alg) { - case PGP_PKA_DSA: - ret = pgp_dsa_verify(hash, length, &sig->info.sig.dsa, - &signer->key.dsa); - break; - - case PGP_PKA_RSA: - ret = rsa_verify(sig->info.hash_alg, hash, length, - &sig->info.sig.rsa, - &signer->key.rsa); - break; - - default: - (void) fprintf(stderr, "pgp_check_sig: unusual alg\n"); - ret = 0; - } - - return ret; -} - -static unsigned -hash_and_check_sig(pgp_hash_t *hash, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - uint8_t hashout[PGP_MAX_HASH_SIZE]; - unsigned n; - - n = hash->finish(hash, hashout); - return pgp_check_sig(hashout, n, sig, signer); -} - -static unsigned -finalise_sig(pgp_hash_t *hash, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - hash_add_trailer(hash, sig); - return hash_and_check_sig(hash, sig, signer); -} - -/** - * \ingroup Core_Signature - * - * \brief Verify a certification signature. - * - * \param key The public key that was signed. - * \param id The user ID that was signed - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return 1 if OK; else 0 - */ -unsigned -pgp_check_useridcert_sig(const pgp_pubkey_t *key, - const uint8_t *id, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - pgp_hash_t hash; - size_t userid_len; - - userid_len = strlen((const char *) id); - init_key_sig(&hash, sig, key); - if (sig->info.version == PGP_V4) { - pgp_hash_add_int(&hash, 0xb4, 1); - pgp_hash_add_int(&hash, (unsigned)userid_len, 4); - } - hash.add(&hash, id, (unsigned)userid_len); - return finalise_sig(&hash, sig, signer); -} - -/** - * \ingroup Core_Signature - * - * Verify a certification signature. - * - * \param key The public key that was signed. - * \param attribute The user attribute that was signed - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return 1 if OK; else 0 - */ -unsigned -pgp_check_userattrcert_sig(const pgp_pubkey_t *key, - const pgp_data_t *attribute, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - pgp_hash_t hash; - - init_key_sig(&hash, sig, key); - if (sig->info.version == PGP_V4) { - pgp_hash_add_int(&hash, 0xd1, 1); - pgp_hash_add_int(&hash, (unsigned)attribute->len, 4); - } - hash.add(&hash, attribute->contents, (unsigned)attribute->len); - return finalise_sig(&hash, sig, signer); -} - -/** - * \ingroup Core_Signature - * - * Verify a subkey signature. - * - * \param key The public key whose subkey was signed. - * \param subkey The subkey of the public key that was signed. - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return 1 if OK; else 0 - */ -unsigned -pgp_check_subkey_sig(const pgp_pubkey_t *key, - const pgp_pubkey_t *subkey, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - pgp_hash_t hash; - unsigned ret; - - init_key_sig(&hash, sig, key); - hash_add_key(&hash, subkey); - ret = finalise_sig(&hash, sig, signer); - return ret; -} - -/** - * \ingroup Core_Signature - * - * Verify a direct signature. - * - * \param key The public key which was signed. - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return 1 if OK; else 0 - */ -unsigned -pgp_check_direct_sig(const pgp_pubkey_t *key, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - pgp_hash_t hash; - unsigned ret; - - init_key_sig(&hash, sig, key); - ret = finalise_sig(&hash, sig, signer); - return ret; -} - -/** - * \ingroup Core_Signature - * - * Verify a signature on a hash (the hash will have already been fed - * the material that was being signed, for example signed cleartext). - * - * \param hash A hash structure of appropriate type that has been fed - * the material to be signed. This MUST NOT have been finalised. - * \param sig The signature to be verified. - * \param signer The public key of the signer. - * \return 1 if OK; else 0 - */ -unsigned -pgp_check_hash_sig(pgp_hash_t *hash, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - return (sig->info.hash_alg == hash->alg) ? - finalise_sig(hash, sig, signer) : - 0; -} - -static void -start_sig_in_mem(pgp_create_sig_t *sig) -{ - /* since this has subpackets and stuff, we have to buffer the whole */ - /* thing to get counts before writing. */ - sig->mem = pgp_memory_new(); - pgp_memory_init(sig->mem, 100); - pgp_writer_set_memory(sig->output, sig->mem); - - /* write nearly up to the first subpacket */ - pgp_write_scalar(sig->output, (unsigned)sig->sig.info.version, 1); - pgp_write_scalar(sig->output, (unsigned)sig->sig.info.type, 1); - pgp_write_scalar(sig->output, (unsigned)sig->sig.info.key_alg, 1); - pgp_write_scalar(sig->output, (unsigned)sig->sig.info.hash_alg, 1); - - /* dummy hashed subpacket count */ - sig->hashoff = (unsigned)pgp_mem_len(sig->mem); - pgp_write_scalar(sig->output, 0, 2); -} - -/** - * \ingroup Core_Signature - * - * pgp_sig_start() creates a V4 public key signature with a SHA1 hash. - * - * \param sig The signature structure to initialise - * \param key The public key to be signed - * \param id The user ID being bound to the key - * \param type Signature type - */ -void -pgp_sig_start_key_sig(pgp_create_sig_t *sig, - const pgp_pubkey_t *key, - const pgp_pubkey_t *subkey, // added by Delta Chat to allow subkey binding signatures, EDIT BY MR (bp) - const uint8_t *id, - pgp_sig_type_t type) -{ - sig->output = pgp_output_new(); - - /* XXX: refactor with check (in several ways - check should - * probably use the buffered writer to construct packets - * (done), and also should share code for hash calculation) */ - sig->sig.info.version = PGP_V4; - sig->sig.info.hash_alg = PGP_HASH_SHA256; // changed by Delta Chat from PGP_HASH_SHA1 to PGP_HASH_SHA256, EDIT BY MR (bp) - sig->sig.info.key_alg = key->alg; - sig->sig.info.type = type; - sig->hashlen = (unsigned)-1; - init_key_sig(&sig->hash, &sig->sig, key); - if( subkey ) { - hash_add_key(&sig->hash, subkey); // added by Delta Chat to allow subkey binding signatures, EDIT BY MR (bp) - } - - if( id ) { // condition added by Delta Chat to allow subkey binding signatures, EDIT BY MR (bp) - pgp_hash_add_int(&sig->hash, 0xb4, 1); - //pgp_hash_add_int(&sig->hash, (unsigned)strlen((const char *) id), 4); - //sig->hash.add(&sig->hash, id, (unsigned)strlen((const char *) id)); - } - - start_sig_in_mem(sig); -} - -void -pgp_sig_start_key_rev(pgp_create_sig_t *sig, - const pgp_pubkey_t *key, - pgp_sig_type_t type) -{ - sig->output = pgp_output_new(); - - sig->sig.info.version = PGP_V4; - sig->sig.info.hash_alg = PGP_HASH_SHA1; - sig->sig.info.key_alg = key->alg; - sig->sig.info.type = type; - sig->hashlen = (unsigned)-1; - init_key_sig(&sig->hash, &sig->sig, key); - start_sig_in_mem(sig); -} - -/** - * \ingroup Core_Signature - * - * Create a V4 public key signature over some cleartext. - * - * \param sig The signature structure to initialise - * \param id - * \param type - * \todo Expand description. Allow other hashes. - */ - -void -pgp_start_sig(pgp_create_sig_t *sig, - const pgp_seckey_t *key, - const pgp_hash_alg_t hash, - const pgp_sig_type_t type) -{ - sig->output = pgp_output_new(); - - /* XXX: refactor with check (in several ways - check should - * probably use the buffered writer to construct packets - * (done), and also should share code for hash calculation) */ - sig->sig.info.version = PGP_V4; - sig->sig.info.key_alg = key->pubkey.alg; - sig->sig.info.hash_alg = hash; - sig->sig.info.type = type; - - sig->hashlen = (unsigned)-1; - - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "initialising hash for sig in mem\n"); - } - initialise_hash(&sig->hash, &sig->sig); - start_sig_in_mem(sig); -} - -/** - * \ingroup Core_Signature - * - * Add plaintext data to a signature-to-be. - * - * \param sig The signature-to-be. - * \param buf The plaintext data. - * \param length The amount of plaintext data. - */ -void -pgp_sig_add_data(pgp_create_sig_t *sig, const void *buf, size_t length) -{ - sig->hash.add(&sig->hash, buf, (unsigned)length); -} - -/** - * \ingroup Core_Signature - * - * Mark the end of the hashed subpackets in the signature - * - * \param sig - */ - -unsigned -pgp_end_hashed_subpkts(pgp_create_sig_t *sig) -{ - sig->hashlen = (unsigned)(pgp_mem_len(sig->mem) - sig->hashoff - 2); - pgp_memory_place_int(sig->mem, sig->hashoff, sig->hashlen, 2); - /* dummy unhashed subpacket count */ - sig->unhashoff = (unsigned)pgp_mem_len(sig->mem); - return pgp_write_scalar(sig->output, 0, 2); -} - -/** - * \ingroup Core_Signature - * - * Write out a signature - * - * \param sig - * \param key - * \param seckey - * \param info - * - */ - -unsigned -pgp_write_sig(pgp_output_t *output, - pgp_create_sig_t *sig, - const pgp_pubkey_t *key, - const pgp_seckey_t *seckey) -{ - unsigned ret = 0; - size_t len = pgp_mem_len(sig->mem); - - /* check key not decrypted */ - switch (seckey->pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (seckey->key.rsa.d == NULL) { - (void) fprintf(stderr, "pgp_write_sig: null rsa.d\n"); - return 0; - } - break; - - case PGP_PKA_DSA: - if (seckey->key.dsa.x == NULL) { - (void) fprintf(stderr, "pgp_write_sig: null dsa.x\n"); - return 0; - } - break; - - default: - (void) fprintf(stderr, "Unsupported algorithm %d\n", - seckey->pubkey.alg); - return 0; - } - - if (sig->hashlen == (unsigned) -1) { - (void) fprintf(stderr, - "ops_write_sig: bad hashed data len\n"); - return 0; - } - - pgp_memory_place_int(sig->mem, sig->unhashoff, - (unsigned)(len - sig->unhashoff - 2), 2); - - /* add the packet from version number to end of hashed subpackets */ - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "ops_write_sig: hashed packet info\n"); - } - sig->hash.add(&sig->hash, pgp_mem_data(sig->mem), sig->unhashoff); - - /* add final trailer */ - pgp_hash_add_int(&sig->hash, (unsigned)sig->sig.info.version, 1); - pgp_hash_add_int(&sig->hash, 0xff, 1); - /* +6 for version, type, pk alg, hash alg, hashed subpacket length */ - pgp_hash_add_int(&sig->hash, sig->hashlen + 6, 4); - - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "ops_write_sig: done writing hashed\n"); - } - /* XXX: technically, we could figure out how big the signature is */ - /* and write it directly to the output instead of via memory. */ - switch (seckey->pubkey.alg) { - case PGP_PKA_RSA: - case PGP_PKA_RSA_ENCRYPT_ONLY: - case PGP_PKA_RSA_SIGN_ONLY: - if (!rsa_sign(&sig->hash, &key->key.rsa, &seckey->key.rsa, - sig->output)) { - (void) fprintf(stderr, - "pgp_write_sig: rsa_sign failure\n"); - return 0; - } - break; - - case PGP_PKA_DSA: - if (!dsa_sign(&sig->hash, &key->key.dsa, &seckey->key.dsa, - sig->output)) { - (void) fprintf(stderr, - "pgp_write_sig: dsa_sign failure\n"); - return 0; - } - break; - - default: - (void) fprintf(stderr, "Unsupported algorithm %d\n", - seckey->pubkey.alg); - return 0; - } - - ret = pgp_write_ptag(output, PGP_PTAG_CT_SIGNATURE); - if (ret) { - len = pgp_mem_len(sig->mem); - ret = pgp_write_length(output, (unsigned)len) && - pgp_write(output, pgp_mem_data(sig->mem), (unsigned)len); - } - pgp_memory_free(sig->mem); - - if (ret == 0) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", - "Cannot write signature"); - } - return ret; -} - -unsigned -pgp_add_creation_time(pgp_create_sig_t *sig, time_t when) -{ - pgp_content_enum tag; - - tag = PGP_PTAG_SS_CREATION_TIME; - - sig->sig.info.birthtime = when; - sig->sig.info.birthtime_set = 1; - - return pgp_write_ss_header(sig->output, 5, tag) && - pgp_write_scalar(sig->output, (unsigned int)when, 4); -} - -unsigned -pgp_add_sig_expiration_time(pgp_create_sig_t *sig, time_t duration) -{ - pgp_content_enum tag; - - tag = PGP_PTAG_SS_EXPIRATION_TIME; - - sig->sig.info.duration = duration; - sig->sig.info.duration_set = 1; - - return pgp_write_ss_header(sig->output, 5, tag) && - pgp_write_scalar(sig->output, (unsigned int)duration, 4); -} - -unsigned -pgp_add_key_expiration_time(pgp_create_sig_t *sig, time_t duration) -{ - pgp_content_enum tag; - - tag = PGP_PTAG_SS_KEY_EXPIRY; - - sig->sig.info.key_expiry = duration; - sig->sig.info.key_expiry_set = 1; - - return pgp_write_ss_header(sig->output, 5, tag) && - pgp_write_scalar(sig->output, (unsigned int)duration, 4); -} - -unsigned -pgp_add_key_flags(pgp_create_sig_t *sig, uint8_t flags) -{ - pgp_content_enum tag; - - tag = PGP_PTAG_SS_KEY_FLAGS; - - sig->sig.info.key_flags = flags; - sig->sig.info.key_flags_set = 1; - - return pgp_write_ss_header(sig->output, 2, tag) && - pgp_write_scalar(sig->output, (unsigned int)flags, 1); -} - -#if 0 /////// -unsigned -pgp_add_key_prefs(pgp_create_sig_t *sig) -{ - - /* Mimic of GPG default settings, limited to supported algos */ - - return - /* Symmetric algo prefs */ - pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_SKA) && - pgp_write_scalar(sig->output, PGP_SA_AES_256, 1) && - pgp_write_scalar(sig->output, PGP_SA_AES_128, 1) && - pgp_write_scalar(sig->output, PGP_SA_CAST5, 1) && - pgp_write_scalar(sig->output, PGP_SA_TRIPLEDES, 1) && - pgp_write_scalar(sig->output, PGP_SA_IDEA, 1) && - - /* Hash algo prefs */ - pgp_write_ss_header(sig->output, 6, PGP_PTAG_SS_PREFERRED_HASH) && - pgp_write_scalar(sig->output, PGP_HASH_SHA256, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA1, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA384, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA512, 1) && - pgp_write_scalar(sig->output, PGP_HASH_SHA224, 1) && - - /* Compression algo prefs */ - pgp_write_ss_header(sig->output, 3, PGP_PTAG_SS_PREF_COMPRESS) && - pgp_write_scalar(sig->output, PGP_C_ZLIB, 1) && - pgp_write_scalar(sig->output, PGP_C_BZIP2, 1); -} -#endif ////// - -unsigned -pgp_add_key_features(pgp_create_sig_t *sig) -{ - pgp_content_enum tag; - - tag = PGP_PTAG_SS_FEATURES; - - return pgp_write_ss_header(sig->output, 2, tag) && - pgp_write_scalar(sig->output, 0x01, 1); -} - -/** - * \ingroup Core_Signature - * - * Adds issuer's key ID to the signature - * - * \param sig - * \param keyid - */ - -unsigned -pgp_add_issuer_keyid(pgp_create_sig_t *sig, - const uint8_t keyid[PGP_KEY_ID_SIZE]) -{ - return pgp_write_ss_header(sig->output, PGP_KEY_ID_SIZE + 1, - PGP_PTAG_SS_ISSUER_KEY_ID) && - pgp_write(sig->output, keyid, PGP_KEY_ID_SIZE); -} - -/** - * \ingroup Core_Signature - * - * Adds primary user ID to the signature - * - * \param sig - * \param primary - */ -void -pgp_add_primary_userid(pgp_create_sig_t *sig, unsigned primary) -{ - pgp_write_ss_header(sig->output, 2, PGP_PTAG_SS_PRIMARY_USER_ID); - pgp_write_scalar(sig->output, primary, 1); -} - -unsigned -pgp_add_revocation_reason( - pgp_create_sig_t *sig, - uint8_t code, const char *reason) -{ - size_t rlen = reason ? strlen(reason) : 0; - return pgp_write_ss_header( - sig->output, rlen + 1, - PGP_PTAG_SS_REVOCATION_REASON) && - pgp_write_scalar(sig->output, code, 1) && - pgp_write(sig->output, reason, (unsigned int)rlen); -} - -/** - * \ingroup Core_Signature - * - * Get the hash structure in use for the signature. - * - * \param sig The signature structure. - * \return The hash structure. - */ -pgp_hash_t * -pgp_sig_get_hash(pgp_create_sig_t *sig) -{ - return &sig->hash; -} - -/* open up an output file */ -#if 0 ////// -static int -open_output_file(pgp_output_t **output, - const char *inname, - const char *outname, - const char *suffix, - const unsigned overwrite) -{ - int fd; - - /* setup output file */ - if (outname) { - fd = pgp_setup_file_write(output, outname, overwrite); - } else { - unsigned flen = (unsigned)(strlen(inname) + 4 + 1); - char *f = NULL; - - if ((f = calloc(1, flen)) == NULL) { - (void) fprintf(stderr, "open_output_file: bad alloc\n"); - fd = -1; - } else { - (void) snprintf(f, flen, "%s.%s", inname, suffix); - fd = pgp_setup_file_write(output, f, overwrite); - free(f); - } - } - return fd; -} -#endif ////// - -/** -\ingroup HighLevel_Sign -\brief Sign a file -\param inname Input filename -\param outname Output filename. If NULL, a name is constructed from the input filename. -\param seckey Secret Key to use for signing -\param armored Write armoured text, if set. -\param overwrite May overwrite existing file, if set. -\return 1 if OK; else 0; - -*/ -#if 0 ////// -unsigned -pgp_sign_file(pgp_io_t *io, - const char *inname, - const char *outname, - const pgp_seckey_t *seckey, - const char *hashname, - const time_t from, - const time_t duration, - const unsigned armored, - const unsigned cleartext, - const unsigned overwrite) -{ - pgp_create_sig_t *sig; - pgp_sig_type_t sig_type; - pgp_hash_alg_t hash_alg; - pgp_memory_t *infile; - pgp_output_t *output; - pgp_hash_t *hash; - unsigned ret; - uint8_t keyid[PGP_KEY_ID_SIZE]; - int fd_out; - - sig = NULL; - sig_type = PGP_SIG_BINARY; - infile = NULL; - output = NULL; - hash = NULL; - - /* find the hash algorithm */ - hash_alg = pgp_str_to_hash_alg(hashname); - if (hash_alg == PGP_HASH_UNKNOWN) { - (void) fprintf(io->errs, - "pgp_sign_file: unknown hash algorithm: \"%s\"\n", - hashname); - return 0; - } - - /* read input file into buf */ - infile = pgp_memory_new(); - if (!pgp_mem_readfile(infile, inname)) { - return 0; - } - - /* setup output file */ - fd_out = open_output_file(&output, inname, outname, - (armored) ? "asc" : "gpg", overwrite); - if (fd_out < 0) { - pgp_memory_free(infile); - return 0; - } - - /* set up signature */ - sig = pgp_create_sig_new(); - if (!sig) { - pgp_memory_free(infile); - pgp_teardown_file_write(output, fd_out); - return 0; - } - - pgp_start_sig(sig, seckey, hash_alg, sig_type); - - if (cleartext) { - if (pgp_writer_push_clearsigned(output, sig) != 1) { - return 0; - } - - /* Do the signing */ - pgp_write(output, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile)); - pgp_memory_free(infile); - - /* add signature with subpackets: */ - /* - creation time */ - /* - key id */ - ret = pgp_writer_use_armored_sig(output) && - pgp_add_creation_time(sig, from) && - pgp_add_sig_expiration_time(sig, duration); - if (ret == 0) { - pgp_teardown_file_write(output, fd_out); - return 0; - } - - pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); - ret = pgp_add_issuer_keyid(sig, keyid) && - pgp_end_hashed_subpkts(sig) && - pgp_write_sig(output, sig, &seckey->pubkey, seckey); - - pgp_teardown_file_write(output, fd_out); - - if (ret == 0) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", - "Cannot sign file as cleartext"); - } - } else { - /* set armoured/not armoured here */ - if (armored) { - pgp_writer_push_armor_msg(output); - } - - /* write one_pass_sig */ - pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type); - - /* hash file contents */ - hash = pgp_sig_get_hash(sig); - hash->add(hash, pgp_mem_data(infile), (unsigned)pgp_mem_len(infile)); - -#if 1 - /* output file contents as Literal Data packet */ - pgp_write_litdata(output, pgp_mem_data(infile), - (const int)pgp_mem_len(infile), - PGP_LDT_BINARY); -#else - /* XXX - agc - sync with writer.c 1094 for ops_writez */ - pgp_setup_memory_write(&litoutput, &litmem, bufsz); - pgp_setup_memory_write(&zoutput, &zmem, bufsz); - pgp_write_litdata(litoutput, - pgp_mem_data(pgp_mem_data(infile), - (const int)pgp_mem_len(infile), PGP_LDT_BINARY); - pgp_writez(zoutput, pgp_mem_data(litmem), pgp_mem_len(litmem)); -#endif - - /* add creation time to signature */ - pgp_add_creation_time(sig, from); - pgp_add_sig_expiration_time(sig, duration); - /* add key id to signature */ - pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); - pgp_add_issuer_keyid(sig, keyid); - pgp_end_hashed_subpkts(sig); - pgp_write_sig(output, sig, &seckey->pubkey, seckey); - - /* tidy up */ - pgp_teardown_file_write(output, fd_out); - - pgp_create_sig_delete(sig); - pgp_memory_free(infile); - - ret = 1; - } - - return ret; -} -#endif /////// - -/** -\ingroup HighLevel_Sign -\brief Signs a buffer -\param input Input text to be signed -\param input_len Length of input text -\param sig_type Signature type -\param seckey Secret Key -\param armored Write armoured text, if set -\return New pgp_memory_t struct containing signed text -\note It is the caller's responsibility to call pgp_memory_free(me) - -*/ -pgp_memory_t * -pgp_sign_buf(pgp_io_t *io, - const void *input, - const size_t insize, - const pgp_seckey_t *seckey, - const time_t from, - const time_t duration, - const char *hashname, - const unsigned armored, - const unsigned cleartext) -{ - pgp_litdata_enum ld_type; - pgp_create_sig_t *sig; - pgp_sig_type_t sig_type; - pgp_hash_alg_t hash_alg; - pgp_output_t *output; - pgp_memory_t *mem; - uint8_t keyid[PGP_KEY_ID_SIZE]; - pgp_hash_t *hash; - unsigned ret; - - sig = NULL; - sig_type = PGP_SIG_BINARY; - output = NULL; - mem = pgp_memory_new(); - hash = NULL; - - hash_alg = pgp_str_to_hash_alg(hashname); - if (hash_alg == PGP_HASH_UNKNOWN) { - (void) fprintf(io->errs, - "pgp_sign_buf: unknown hash algorithm: \"%s\"\n", - hashname); - return NULL; - } - - /* setup literal data packet type */ - ld_type = (cleartext) ? PGP_LDT_TEXT : PGP_LDT_BINARY; - - if (input == NULL) { - (void) fprintf(io->errs, - "pgp_sign_buf: null input\n"); - return NULL; - } - - /* set up signature */ - if ((sig = pgp_create_sig_new()) == NULL) { - return NULL; - } - pgp_start_sig(sig, seckey, hash_alg, sig_type); - - /* setup writer */ - pgp_setup_memory_write(&output, &mem, insize); - - if (cleartext) { - /* Do the signing */ - /* add signature with subpackets: */ - /* - creation time */ - /* - key id */ - ret = pgp_writer_push_clearsigned(output, sig) && - pgp_write(output, input, (unsigned)insize) && - pgp_writer_use_armored_sig(output) && - pgp_add_creation_time(sig, from) && - pgp_add_sig_expiration_time(sig, duration); - if (ret == 0) { - return NULL; - } - pgp_output_delete(output); - } else { - /* set armoured/not armoured here */ - if (armored) { - pgp_writer_push_armor_msg(output); - } - if (pgp_get_debug_level(__FILE__)) { - fprintf(io->errs, "** Writing out one pass sig\n"); - } - /* write one_pass_sig */ - pgp_write_one_pass_sig(output, seckey, hash_alg, sig_type); - - /* hash memory */ - hash = pgp_sig_get_hash(sig); - hash->add(hash, input, (unsigned)insize); - - /* output file contents as Literal Data packet */ - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, "** Writing out data now\n"); - } - pgp_write_litdata(output, input, (const int)insize, ld_type); - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, "** After Writing out data now\n"); - } - - /* add creation time to signature */ - pgp_add_creation_time(sig, from); - pgp_add_sig_expiration_time(sig, duration); - /* add key id to signature */ - pgp_keyid(keyid, PGP_KEY_ID_SIZE, &seckey->pubkey, hash_alg); - pgp_add_issuer_keyid(sig, keyid); - pgp_end_hashed_subpkts(sig); - - /* write out sig */ - pgp_write_sig(output, sig, &seckey->pubkey, seckey); - - /* tidy up */ - pgp_writer_close(output); - pgp_create_sig_delete(sig); - } - return mem; -} - -/* sign a file, and put the signature in a separate file */ -#if 0 ////// -int -pgp_sign_detached(pgp_io_t *io, - const char *f, - char *sigfile, - const pgp_seckey_t *seckey, - const char *hash, - const time_t from, - const time_t duration, - const unsigned armored, const unsigned overwrite) -{ - pgp_create_sig_t *sig; - pgp_hash_alg_t hash_alg; - pgp_output_t *output; - pgp_memory_t *mem; - uint8_t keyid[PGP_KEY_ID_SIZE]; - int fd; - - /* find out which hash algorithm to use */ - hash_alg = pgp_str_to_hash_alg(hash); - if (hash_alg == PGP_HASH_UNKNOWN) { - (void) fprintf(io->errs,"Unknown hash algorithm: %s\n", hash); - return 0; - } - - /* setup output file */ - fd = open_output_file(&output, f, sigfile, - (armored) ? "asc" : "sig", overwrite); - if (fd < 0) { - (void) fprintf(io->errs,"Can't open output file: %s\n", f); - return 0; - } - - /* create a new signature */ - sig = pgp_create_sig_new(); - pgp_start_sig(sig, seckey, hash_alg, PGP_SIG_BINARY); - - /* read the contents of 'f', and add that to the signature */ - mem = pgp_memory_new(); - if (!pgp_mem_readfile(mem, f)) { - pgp_teardown_file_write(output, fd); - return 0; - } - /* set armoured/not armoured here */ - if (armored) { - pgp_writer_push_armor_msg(output); - } - pgp_sig_add_data(sig, pgp_mem_data(mem), pgp_mem_len(mem)); - pgp_memory_free(mem); - - /* calculate the signature */ - pgp_add_creation_time(sig, from); - pgp_add_sig_expiration_time(sig, duration); - pgp_keyid(keyid, sizeof(keyid), &seckey->pubkey, hash_alg); - pgp_add_issuer_keyid(sig, keyid); - pgp_end_hashed_subpkts(sig); - pgp_write_sig(output, sig, &seckey->pubkey, seckey); - pgp_teardown_file_write(output, fd); - - return 1; -} -#endif ////// diff --git a/netpgp/symmetric.c b/netpgp/symmetric.c deleted file mode 100644 index 033d1d04b7dcd82fe8112424a8825bbd725f83d8..0000000000000000000000000000000000000000 --- a/netpgp/symmetric.c +++ /dev/null @@ -1,802 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include "netpgp/crypto.h" -#include "netpgp/packet-show.h" - -#include <string.h> - -#ifdef HAVE_OPENSSL_CAST_H -#include <openssl/cast.h> -#endif - -#ifdef HAVE_OPENSSL_IDEA_H -#include <openssl/idea.h> -#endif - -#ifdef HAVE_OPENSSL_AES_H -#include <openssl/aes.h> -#endif - -#ifdef HAVE_OPENSSL_DES_H -#include <openssl/des.h> -#endif - -#ifdef HAVE_OPENSSL_CAMELLIA_H -#include <openssl/camellia.h> -#endif - -#include "netpgp/crypto.h" -#include "netpgp/netpgpdefs.h" - - -static void -std_set_iv(pgp_crypt_t *crypt, const uint8_t *iv) -{ - (void) memcpy(crypt->iv, iv, crypt->blocksize); - crypt->num = 0; -} - -static void -std_set_key(pgp_crypt_t *crypt, const uint8_t *key) -{ - (void) memcpy(crypt->key, key, crypt->keysize); -} - -static void -std_resync(pgp_crypt_t *decrypt) -{ - if ((size_t) decrypt->num == decrypt->blocksize) { - return; - } - - memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ, - (unsigned)decrypt->num); - (void) memcpy(decrypt->civ, decrypt->siv + decrypt->num, - decrypt->blocksize - decrypt->num); - decrypt->num = 0; -} - -static void -std_finish(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - crypt->encrypt_key = NULL; - } - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - crypt->decrypt_key = NULL; - } -} - -static int -cast5_init(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { - (void) fprintf(stderr, "cast5_init: alloc failure\n"); - return 0; - } - CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key); - if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { - (void) fprintf(stderr, "cast5_init: alloc failure\n"); - return 0; - } - CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key); - return 1; -} - -static void -cast5_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT); -} - -static void -cast5_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT); -} - -static void -cast5_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - CAST_cfb64_encrypt(in, out, (long)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - CAST_ENCRYPT); -} - -static void -cast5_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - CAST_cfb64_encrypt(in, out, (long)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - CAST_DECRYPT); -} - -#define TRAILER "","","","",0,NULL,NULL - -static pgp_crypt_t cast5 = -{ - PGP_SA_CAST5, - CAST_BLOCK, - CAST_KEY_LENGTH, - std_set_iv, - std_set_key, - cast5_init, - std_resync, - cast5_block_encrypt, - cast5_block_decrypt, - cast5_cfb_encrypt, - cast5_cfb_decrypt, - std_finish, - TRAILER -}; - -#ifndef OPENSSL_NO_IDEA -static int -idea_init(pgp_crypt_t *crypt) -{ - if (crypt->keysize != IDEA_KEY_LENGTH) { - (void) fprintf(stderr, "idea_init: keysize wrong\n"); - return 0; - } - - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) { - (void) fprintf(stderr, "idea_init: alloc failure\n"); - return 0; - } - - /* note that we don't invert the key when decrypting for CFB mode */ - idea_set_encrypt_key(crypt->key, crypt->encrypt_key); - - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - } - if ((crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) { - (void) fprintf(stderr, "idea_init: alloc failure\n"); - return 0; - } - - idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key); - return 1; -} - -static void -idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - idea_ecb_encrypt(in, out, crypt->encrypt_key); -} - -static void -idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - idea_ecb_encrypt(in, out, crypt->decrypt_key); -} - -static void -idea_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - idea_cfb64_encrypt(in, out, (long)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - CAST_ENCRYPT); -} - -static void -idea_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - idea_cfb64_encrypt(in, out, (long)count, - crypt->decrypt_key, crypt->iv, &crypt->num, - CAST_DECRYPT); -} - -static const pgp_crypt_t idea = -{ - PGP_SA_IDEA, - IDEA_BLOCK, - IDEA_KEY_LENGTH, - std_set_iv, - std_set_key, - idea_init, - std_resync, - idea_block_encrypt, - idea_block_decrypt, - idea_cfb_encrypt, - idea_cfb_decrypt, - std_finish, - TRAILER -}; -#endif /* OPENSSL_NO_IDEA */ - -/* AES with 128-bit key (AES) */ - -#define KEYBITS_AES128 128 - -static int -aes128_init(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { - (void) fprintf(stderr, "aes128_init: alloc failure\n"); - return 0; - } - if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128, - crypt->encrypt_key)) { - fprintf(stderr, "aes128_init: Error setting encrypt_key\n"); - } - - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - } - if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { - (void) fprintf(stderr, "aes128_init: alloc failure\n"); - return 0; - } - if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128, - crypt->decrypt_key)) { - fprintf(stderr, "aes128_init: Error setting decrypt_key\n"); - } - return 1; -} - -static void -aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - AES_encrypt(in, out, crypt->encrypt_key); -} - -static void -aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - AES_decrypt(in, out, crypt->decrypt_key); -} - -static void -aes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - AES_cfb128_encrypt(in, out, (unsigned)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - AES_ENCRYPT); -} - -static void -aes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - AES_cfb128_encrypt(in, out, (unsigned)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - AES_DECRYPT); -} - -static const pgp_crypt_t aes128 = -{ - PGP_SA_AES_128, - AES_BLOCK_SIZE, - KEYBITS_AES128 / 8, - std_set_iv, - std_set_key, - aes128_init, - std_resync, - aes_block_encrypt, - aes_block_decrypt, - aes_cfb_encrypt, - aes_cfb_decrypt, - std_finish, - TRAILER -}; - -/* AES with 256-bit key */ - -#define KEYBITS_AES256 256 - -static int -aes256_init(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { - (void) fprintf(stderr, "aes256_init: alloc failure\n"); - return 0; - } - if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256, - crypt->encrypt_key)) { - fprintf(stderr, "aes256_init: Error setting encrypt_key\n"); - free(crypt->encrypt_key); - crypt->encrypt_key = NULL; - return 0; - } - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - } - if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { - (void) fprintf(stderr, "aes256_init: alloc failure\n"); - free(crypt->encrypt_key); - crypt->encrypt_key = NULL; - return 0; - } - if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256, - crypt->decrypt_key)) { - fprintf(stderr, "aes256_init: Error setting decrypt_key\n"); - free(crypt->encrypt_key); - crypt->encrypt_key = NULL; - free(crypt->decrypt_key); - crypt->decrypt_key = NULL; - return 0; - } - return 1; -} - -static const pgp_crypt_t aes256 = -{ - PGP_SA_AES_256, - AES_BLOCK_SIZE, - KEYBITS_AES256 / 8, - std_set_iv, - std_set_key, - aes256_init, - std_resync, - aes_block_encrypt, - aes_block_decrypt, - aes_cfb_encrypt, - aes_cfb_decrypt, - std_finish, - TRAILER -}; - -/* Triple DES */ - -static int -tripledes_init(pgp_crypt_t *crypt) -{ - DES_key_schedule *keys; - int n; - - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) { - (void) fprintf(stderr, "tripledes_init: alloc failure\n"); - return 0; - } - for (n = 0; n < 3; ++n) { - DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8), - &keys[n]); - } - return 1; -} - -static void -tripledes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - DES_key_schedule *keys = crypt->encrypt_key; - - DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], - DES_ENCRYPT); -} - -static void -tripledes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - DES_key_schedule *keys = crypt->encrypt_key; - - DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], - DES_DECRYPT); -} - -static void -tripledes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, - size_t count) -{ - DES_key_schedule *keys = crypt->encrypt_key; - - DES_ede3_cfb64_encrypt(in, out, (long)count, - &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, - &crypt->num, DES_ENCRYPT); -} - -static void -tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, - size_t count) -{ - DES_key_schedule *keys = crypt->encrypt_key; - - DES_ede3_cfb64_encrypt(in, out, (long)count, - &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, - &crypt->num, DES_DECRYPT); -} - -static const pgp_crypt_t tripledes = -{ - PGP_SA_TRIPLEDES, - 8, - 24, - std_set_iv, - std_set_key, - tripledes_init, - std_resync, - tripledes_block_encrypt, - tripledes_block_decrypt, - tripledes_cfb_encrypt, - tripledes_cfb_decrypt, - std_finish, - TRAILER -}; - -#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) -/* Camellia with 128-bit key (CAMELLIA) */ - -#define KEYBITS_CAMELLIA128 128 - -static int -camellia128_init(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { - (void) fprintf(stderr, "camellia128_init: alloc failure\n"); - return 0; - } - if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->encrypt_key)) { - fprintf(stderr, "camellia128_init: Error setting encrypt_key\n"); - } - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - } - if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { - (void) fprintf(stderr, "camellia128_init: alloc failure\n"); - return 0; - } - if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->decrypt_key)) { - fprintf(stderr, "camellia128_init: Error setting decrypt_key\n"); - } - return 1; -} - -static void -camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - Camellia_encrypt(in, out, crypt->encrypt_key); -} - -static void -camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) -{ - Camellia_decrypt(in, out, crypt->decrypt_key); -} - -static void -camellia_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - Camellia_cfb128_encrypt(in, out, (unsigned)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - CAMELLIA_ENCRYPT); -} - -static void -camellia_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) -{ - Camellia_cfb128_encrypt(in, out, (unsigned)count, - crypt->encrypt_key, crypt->iv, &crypt->num, - CAMELLIA_DECRYPT); -} - -static const pgp_crypt_t camellia128 = -{ - PGP_SA_CAMELLIA_128, - CAMELLIA_BLOCK_SIZE, - KEYBITS_CAMELLIA128 / 8, - std_set_iv, - std_set_key, - camellia128_init, - std_resync, - camellia_block_encrypt, - camellia_block_decrypt, - camellia_cfb_encrypt, - camellia_cfb_decrypt, - std_finish, - TRAILER -}; - -/* Camellia with 256-bit key (CAMELLIA) */ - -#define KEYBITS_CAMELLIA256 256 - -static int -camellia256_init(pgp_crypt_t *crypt) -{ - if (crypt->encrypt_key) { - free(crypt->encrypt_key); - } - if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { - (void) fprintf(stderr, "camellia256_init: alloc failure\n"); - return 0; - } - if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->encrypt_key)) { - fprintf(stderr, "camellia256_init: Error setting encrypt_key\n"); - } - if (crypt->decrypt_key) { - free(crypt->decrypt_key); - } - if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { - (void) fprintf(stderr, "camellia256_init: alloc failure\n"); - return 0; - } - if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->decrypt_key)) { - fprintf(stderr, "camellia256_init: Error setting decrypt_key\n"); - } - return 1; -} - -static const pgp_crypt_t camellia256 = -{ - PGP_SA_CAMELLIA_256, - CAMELLIA_BLOCK_SIZE, - KEYBITS_CAMELLIA256 / 8, - std_set_iv, - std_set_key, - camellia256_init, - std_resync, - camellia_block_encrypt, - camellia_block_decrypt, - camellia_cfb_encrypt, - camellia_cfb_decrypt, - std_finish, - TRAILER -}; -#endif - - -static const pgp_crypt_t * -get_proto(pgp_symm_alg_t alg) -{ - switch (alg) { - case PGP_SA_CAST5: - return &cast5; -#ifndef OPENSSL_NO_IDEA - case PGP_SA_IDEA: - return &idea; -#endif /* OPENSSL_NO_IDEA */ - case PGP_SA_AES_128: - return &aes128; - case PGP_SA_AES_256: - return &aes256; -#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) - case PGP_SA_CAMELLIA_128: - return &camellia128; - case PGP_SA_CAMELLIA_256: - return &camellia256; -#endif - case PGP_SA_TRIPLEDES: - return &tripledes; - default: - (void) fprintf(stderr, "Unknown algorithm: %d (%s)\n", - alg, pgp_show_symm_alg(alg)); - } - return NULL; -} - -int -pgp_crypt_any(pgp_crypt_t *crypt, pgp_symm_alg_t alg) -{ - const pgp_crypt_t *ptr = get_proto(alg); - - if (ptr) { - *crypt = *ptr; - return 1; - } else { - (void) memset(crypt, 0x0, sizeof(*crypt)); - return 0; - } -} - -unsigned -pgp_block_size(pgp_symm_alg_t alg) -{ - const pgp_crypt_t *p = get_proto(alg); - - return (p == NULL) ? 0 : (unsigned)p->blocksize; -} - -unsigned -pgp_key_size(pgp_symm_alg_t alg) -{ - const pgp_crypt_t *p = get_proto(alg); - - return (p == NULL) ? 0 : (unsigned)p->keysize; -} - -void -pgp_encrypt_init(pgp_crypt_t *encrypt) -{ - /* \todo should there be a separate pgp_encrypt_init? */ - pgp_decrypt_init(encrypt); -} - -void -pgp_decrypt_init(pgp_crypt_t *decrypt) -{ - decrypt->base_init(decrypt); - decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv); - (void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize); - decrypt->num = 0; -} - -size_t -pgp_decrypt_se(pgp_crypt_t *decrypt, void *outvoid, const void *invoid, - size_t count) -{ - const uint8_t *in = invoid; - uint8_t *out = outvoid; - int saved = (int)count; - - /* - * in order to support v3's weird resyncing we have to implement CFB - * mode ourselves - */ - while (count-- > 0) { - uint8_t t; - - if ((size_t) decrypt->num == decrypt->blocksize) { - (void) memcpy(decrypt->siv, decrypt->civ, - decrypt->blocksize); - decrypt->block_decrypt(decrypt, decrypt->civ, - decrypt->civ); - decrypt->num = 0; - } - t = decrypt->civ[decrypt->num]; - *out++ = t ^ (decrypt->civ[decrypt->num++] = *in++); - } - - return (size_t)saved; -} - -size_t -pgp_encrypt_se(pgp_crypt_t *encrypt, void *outvoid, const void *invoid, - size_t count) -{ - const uint8_t *in = invoid; - uint8_t *out = outvoid; - int saved = (int)count; - - /* - * in order to support v3's weird resyncing we have to implement CFB - * mode ourselves - */ - while (count-- > 0) { - if ((size_t) encrypt->num == encrypt->blocksize) { - (void) memcpy(encrypt->siv, encrypt->civ, - encrypt->blocksize); - encrypt->block_encrypt(encrypt, encrypt->civ, - encrypt->civ); - encrypt->num = 0; - } - encrypt->civ[encrypt->num] = *out++ = - encrypt->civ[encrypt->num] ^ *in++; - ++encrypt->num; - } - - return (size_t)saved; -} - -/** -\ingroup HighLevel_Supported -\brief Is this Symmetric Algorithm supported? -\param alg Symmetric Algorithm to check -\return 1 if supported; else 0 -*/ -unsigned -pgp_is_sa_supported(pgp_symm_alg_t alg) -{ - switch (alg) { - case PGP_SA_AES_128: - case PGP_SA_AES_256: - case PGP_SA_CAST5: - case PGP_SA_TRIPLEDES: -#if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) - case PGP_SA_CAMELLIA_128: - case PGP_SA_CAMELLIA_256: -#endif -#ifndef OPENSSL_NO_IDEA - case PGP_SA_IDEA: -#endif - return 1; - - default: - fprintf(stderr, "\nWarning: %s not supported\n", - pgp_show_symm_alg(alg)); - return 0; - } -} - -size_t -pgp_encrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in, - size_t count) -{ - if (!pgp_is_sa_supported(crypt->alg)) { - return 0; - } - - crypt->cfb_encrypt(crypt, out, in, count); - - /* \todo test this number was encrypted */ - return count; -} - -size_t -pgp_decrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in, - size_t count) -{ - if (!pgp_is_sa_supported(crypt->alg)) { - return 0; - } - - crypt->cfb_decrypt(crypt, out, in, count); - - /* \todo check this number was in fact decrypted */ - return count; -} diff --git a/netpgp/validate.c b/netpgp/validate.c deleted file mode 100644 index c8228bc23070b2e82e72fcbeba87c046bec816bd..0000000000000000000000000000000000000000 --- a/netpgp/validate.c +++ /dev/null @@ -1,1216 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> - -#include <string.h> -#include <stdio.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#include "netpgp/packet-parse.h" -#include "netpgp/packet-show.h" -#include "netpgp/keyring.h" -#include "netpgp/signature.h" -#include "netpgp/netpgpsdk.h" -#include "netpgp/readerwriter.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/memory.h" -#include "netpgp/packet.h" -#include "netpgp/crypto.h" -#include "netpgp/validate.h" - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -#if defined(ANDROID) || defined(__ANDROID__) -char* getpass (const char *prompt) -{ - return strdup(""); -} -#endif - -// FIXME to support seckey decryption again. -// -// static int -// keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors, -// pgp_reader_t *readinfo, -// pgp_cbdata_t *cbinfo) -// { -// validate_reader_t *reader = pgp_reader_get_arg(readinfo); -// -// __PGP_USED(stream); -// __PGP_USED(errors); -// __PGP_USED(cbinfo); -// if (reader->offset == reader->key->packets[reader->packet].length) { -// reader->packet += 1; -// reader->offset = 0; -// } -// if (reader->packet == reader->key->packetc) { -// return 0; -// } -// -// /* -// * we should never be asked to cross a packet boundary in a single -// * read -// */ -// if (reader->key->packets[reader->packet].length < -// reader->offset + length) { -// (void) fprintf(stderr, "keydata_reader: weird length\n"); -// return 0; -// } -// -// (void) memcpy(dest, -// &reader->key->packets[reader->packet].raw[reader->offset], -// length); -// reader->offset += (unsigned)length; -// -// return (int)length; -// } - -static void -free_sig_info(pgp_sig_info_t *sig) -{ - pgp_free_sig_info(sig); - free(sig); -} - - -static int -add_sig_to_list(const pgp_sig_info_t *sig, pgp_sig_info_t **sigs, - unsigned *count) -{ - pgp_sig_info_t *newsigs; - - if (*count == 0) { - newsigs = calloc(*count + 1, sizeof(pgp_sig_info_t)); - } else { - newsigs = realloc(*sigs, - (*count + 1) * sizeof(pgp_sig_info_t)); - } - if (newsigs == NULL) { - (void) fprintf(stderr, "add_sig_to_list: alloc failure\n"); - return 0; - } - *sigs = newsigs; - copy_sig_info(&(*sigs)[*count], sig); - *count += 1; - return 1; -} - -/* -The hash value is calculated by the following method: -+ hash the data using the given digest algorithm -+ hash the hash value onto the end -+ hash the trailer - 6 bytes - [PGP_V4][0xff][len >> 24][len >> 16][len >> 8][len & 0xff] -to give the final hash value that is checked against the one in the signature -*/ - -/* Does the signed hash match the given hash? */ -unsigned -check_binary_sig(const uint8_t *data, - const unsigned len, - const pgp_sig_t *sig, - const pgp_pubkey_t *signer) -{ - unsigned hashedlen; - pgp_hash_t hash; - unsigned n; - uint8_t hashout[PGP_MAX_HASH_SIZE]; - uint8_t trailer[6]; - - pgp_hash_any(&hash, sig->info.hash_alg); - if (!hash.init(&hash)) { - (void) fprintf(stderr, "check_binary_sig: bad hash init\n"); - return 0; - } - hash.add(&hash, data, len); - switch (sig->info.version) { - case PGP_V3: - trailer[0] = sig->info.type; - trailer[1] = (unsigned)(sig->info.birthtime) >> 24; - trailer[2] = (unsigned)(sig->info.birthtime) >> 16; - trailer[3] = (unsigned)(sig->info.birthtime) >> 8; - trailer[4] = (uint8_t)(sig->info.birthtime); - hash.add(&hash, trailer, 5); - break; - - case PGP_V4: - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "v4 hash", sig->info.v4_hashed, - sig->info.v4_hashlen); - } - hash.add(&hash, sig->info.v4_hashed, (unsigned)sig->info.v4_hashlen); - trailer[0] = 0x04; /* version */ - trailer[1] = 0xFF; - hashedlen = (unsigned)sig->info.v4_hashlen; - trailer[2] = (uint8_t)(hashedlen >> 24); - trailer[3] = (uint8_t)(hashedlen >> 16); - trailer[4] = (uint8_t)(hashedlen >> 8); - trailer[5] = (uint8_t)(hashedlen); - hash.add(&hash, trailer, 6); - break; - - default: - (void) fprintf(stderr, "Invalid signature version %d\n", - sig->info.version); - return 0; - } - - n = hash.finish(&hash, hashout); - if (pgp_get_debug_level(__FILE__)) { - hexdump(stdout, "hash out", hashout, n); - } - return pgp_check_sig(hashout, n, sig, signer); -} - -static void validate_key_cb_free (validate_key_cb_t *vdata){ - - /* Free according to previous allocated type */ - if (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) { - pgp_pubkey_free(&vdata->key.pubkey); - pgp_pubkey_free(&vdata->subkey.pubkey); - } else if (vdata->type == PGP_PTAG_CT_SECRET_KEY) { - pgp_seckey_free(&vdata->key.seckey); - if(vdata->subkey.seckey.pubkey.alg) - pgp_seckey_free(&vdata->subkey.seckey); - } - memset(&vdata->key, 0, sizeof(vdata->key)); - memset(&vdata->subkey, 0, sizeof(vdata->subkey)); - vdata->type = PGP_PTAG_CT_RESERVED; /* 0 */ - - pgp_userid_free(&vdata->userid); - pgp_data_free(&vdata->userattr); - - if(vdata->valid_sig_info.key_alg) { - pgp_free_sig_info(&vdata->valid_sig_info); - } -} - -pgp_cb_ret_t -pgp_validate_key_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - validate_key_cb_t *vdata; - pgp_error_t **errors; - pgp_io_t *io; - unsigned valid = 0; - - io = cbinfo->io; - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(io->errs, "%s\n", - pgp_show_packet_tag(pkt->tag)); - } - vdata = pgp_callback_arg(cbinfo); - errors = pgp_callback_errors(cbinfo); - - vdata->sig_is_valid &= pkt->tag == PGP_PARSER_PACKET_END; - - switch (pkt->tag) { - case PGP_PTAG_CT_PUBLIC_KEY: - validate_key_cb_free(vdata); - vdata->key.pubkey = content->pubkey; - pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE, - &vdata->key.pubkey, PGP_HASH_SHA1); /* TODO v3*/ - - vdata->last_seen = LS_PRIMARY; - vdata->type = PGP_PTAG_CT_PUBLIC_KEY; - vdata->not_commited = 1; - return PGP_KEEP_MEMORY; - - case PGP_PTAG_CT_SECRET_KEY: - /* TODO - * check pubkey seckey consistency */ - validate_key_cb_free(vdata); - vdata->key.seckey = content->seckey; - pgp_keyid(vdata->pubkeyid, PGP_KEY_ID_SIZE, - &vdata->key.seckey.pubkey, PGP_HASH_SHA1); /* TODO v3*/ - vdata->last_seen = LS_PRIMARY; - vdata->type = PGP_PTAG_CT_SECRET_KEY; - vdata->not_commited = 1; - return PGP_KEEP_MEMORY; - - case PGP_PTAG_CT_PUBLIC_SUBKEY: - if(vdata->type == PGP_PTAG_CT_PUBLIC_KEY && ( - vdata->last_seen == LS_ID || - vdata->last_seen == LS_ATTRIBUTE)){ - pgp_pubkey_free(&vdata->subkey.pubkey); - vdata->subkey.pubkey = content->pubkey; - vdata->last_seen = LS_SUBKEY; - return PGP_KEEP_MEMORY; - }else{ - (void) fprintf(io->errs, - "pgp_validate_key_cb: unexpected public subkey packet"); - vdata->last_seen = LS_UNKNOWN; - return PGP_RELEASE_MEMORY; - } - - case PGP_PTAG_CT_SECRET_SUBKEY: - /* TODO - * check pubkey seckey consistency */ - if(vdata->type == PGP_PTAG_CT_SECRET_KEY && ( - vdata->last_seen == LS_ID || - vdata->last_seen == LS_ATTRIBUTE)){ - if(vdata->subkey.seckey.pubkey.alg) - pgp_seckey_free(&vdata->subkey.seckey); - vdata->subkey.seckey = content->seckey; - vdata->last_seen = LS_SUBKEY; - return PGP_KEEP_MEMORY; - }else{ - (void) fprintf(io->errs, - "pgp_validate_key_cb: unexpected secret subkey packet"); - vdata->last_seen = LS_UNKNOWN; - return PGP_RELEASE_MEMORY; - } - - case PGP_PTAG_CT_USER_ID: - if(vdata->last_seen == LS_PRIMARY || - vdata->last_seen == LS_ATTRIBUTE || - vdata->last_seen == LS_ID){ - if (vdata->userid) { - pgp_userid_free(&vdata->userid); - } - vdata->userid = content->userid; - vdata->last_seen = LS_ID; - return PGP_KEEP_MEMORY; - }else{ - (void) fprintf(io->errs, - "pgp_validate_key_cb: unexpected userID packet"); - vdata->last_seen = LS_UNKNOWN; - return PGP_RELEASE_MEMORY; - } - - case PGP_PTAG_CT_USER_ATTR: - if(vdata->last_seen == LS_PRIMARY || - vdata->last_seen == LS_ATTRIBUTE || - vdata->last_seen == LS_ID){ - if (content->userattr.len == 0) { - (void) fprintf(io->errs, - "pgp_validate_key_cb: user attribute length 0"); - vdata->last_seen = LS_UNKNOWN; - return PGP_RELEASE_MEMORY; - } - (void) fprintf(io->outs, "user attribute, length=%d\n", - (int) content->userattr.len); - if (vdata->userattr.len) { - pgp_data_free(&vdata->userattr); - } - vdata->userattr = content->userattr; - vdata->last_seen = LS_ATTRIBUTE; - return PGP_KEEP_MEMORY; - }else{ - (void) fprintf(io->errs, - "pgp_validate_key_cb: unexpected user attribute\n"); - vdata->last_seen = LS_UNKNOWN; - return PGP_RELEASE_MEMORY; - } - case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */ - case PGP_PTAG_CT_SIGNATURE_FOOTER:{ /* V4 sigs */ - pgp_pubkey_t *sigkey = NULL; - pgp_pubkey_t *primary_pubkey; - - if(vdata->last_seen == LS_UNKNOWN) - break; - - primary_pubkey = - (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ? - &vdata->key.pubkey: - &vdata->key.seckey.pubkey; - - if(vdata->keyring){ - unsigned from; - from = 0; - /* Returned key ignored, care about ID-targeted pubkey only */ - pgp_getkeybyid(io, vdata->keyring, - content->sig.info.signer_id, - &from, &sigkey, NULL, - 1, 0); /* reject revoked, accept expired */ - } else { - /* If no keyring is given to check against - * then this is a self certification check. - * First ensure signature issuer ID is pubkey's ID*/ - if(memcmp(vdata->pubkeyid, - content->sig.info.signer_id, - PGP_KEY_ID_SIZE) == 0){ - sigkey = primary_pubkey; - } - } - if (!sigkey) { - if (vdata->result && !add_sig_to_list(&content->sig.info, - &vdata->result->unknown_sigs, - &vdata->result->unknownc)) { - (void) fprintf(io->errs, - "pgp_validate_key_cb: out of memory"); - return PGP_FINISHED; - } - break; - } - switch (content->sig.info.type) { - case PGP_CERT_GENERIC: - case PGP_CERT_PERSONA: - case PGP_CERT_CASUAL: - case PGP_CERT_POSITIVE: - case PGP_SIG_REV_CERT: - if(vdata->last_seen == LS_ID){ - valid = pgp_check_useridcert_sig( - primary_pubkey, - vdata->userid, - &content->sig, - sigkey); - } else if(vdata->last_seen == LS_ATTRIBUTE) { - valid = pgp_check_userattrcert_sig( - primary_pubkey, - &vdata->userattr, - &content->sig, - sigkey); - } - break; - - case PGP_SIG_REV_SUBKEY: - case PGP_SIG_SUBKEY: - /* - * we ensure that the signing key is the - * primary key we are validating, "vdata->pubkey". - */ - if(vdata->last_seen == LS_SUBKEY && - memcmp(vdata->pubkeyid, - content->sig.info.signer_id, - PGP_KEY_ID_SIZE) == 0 ) - { - valid = pgp_check_subkey_sig( - primary_pubkey, - (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ? - &vdata->subkey.pubkey: - &vdata->subkey.seckey.pubkey, - &content->sig, - primary_pubkey); - } - break; - - case PGP_SIG_REV_KEY: - case PGP_SIG_DIRECT: - if(vdata->last_seen == LS_PRIMARY){ - valid = pgp_check_direct_sig( - primary_pubkey, - &content->sig, - sigkey); - } - break; - - case PGP_SIG_STANDALONE: - case PGP_SIG_PRIMARY: - case PGP_SIG_TIMESTAMP: - case PGP_SIG_3RD_PARTY: - if (vdata->result){ - PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, - "Sig Verification type 0x%02x not done yet\n", - content->sig.info.type); - break; - } - - default: - if (vdata->result){ - PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, - "Unexpected signature type 0x%02x\n", - content->sig.info.type); - } - } - - if (valid) { - if (vdata->result && !add_sig_to_list(&content->sig.info, - &vdata->result->valid_sigs, - &vdata->result->validc)) { - PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s", - "Can't add valid sig to list\n"); - } - vdata->sig_is_valid = 1; - copy_sig_info(&vdata->valid_sig_info, - &content->sig.info); - } else if (vdata->result){ - PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s", - "Bad Sig"); - if (!add_sig_to_list(&content->sig.info, - &vdata->result->invalid_sigs, - &vdata->result->invalidc)) { - PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, "%s", - "Can't add invalid sig to list\n"); - } - } - break; - } - case PGP_PARSER_PACKET_END: - if(vdata->sig_is_valid){ - pgp_cb_ret_t ret = PGP_RELEASE_MEMORY; - if(vdata->on_valid){ - ret = vdata->on_valid(vdata, &content->packet); - } - vdata->sig_is_valid = 0; - vdata->not_commited = 0; - return ret; - } - return PGP_RELEASE_MEMORY; - - /* ignore these */ - case PGP_PARSER_PTAG: - case PGP_PTAG_CT_SIGNATURE_HEADER: - case PGP_PTAG_CT_TRUST: - break; - - // case PGP_GET_PASSPHRASE: - // if (vdata->getpassphrase) { - // return vdata->getpassphrase(pkt, cbinfo); - // } - // break; - - default: - // (void) fprintf(stderr, "unexpected tag=0x%x\n", pkt->tag); - return PGP_RELEASE_MEMORY; - } - return PGP_RELEASE_MEMORY; -} - -pgp_cb_ret_t -validate_data_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo) -{ - const pgp_contents_t *content = &pkt->u; - pgp_key_t *signer; - validate_data_cb_t *data; - pgp_pubkey_t *sigkey; - pgp_error_t **errors; - pgp_io_t *io; - unsigned from; - unsigned valid = 0; - - io = cbinfo->io; - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(io->errs, "validate_data_cb: %s\n", - pgp_show_packet_tag(pkt->tag)); - } - data = pgp_callback_arg(cbinfo); - errors = pgp_callback_errors(cbinfo); - switch (pkt->tag) { - case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - /* - * ignore - this gives us the "Armor Header" line "Hash: - * SHA1" or similar - */ - break; - - case PGP_PTAG_CT_LITDATA_HEADER: - /* ignore */ - break; - - case PGP_PTAG_CT_LITDATA_BODY: - data->data.litdata_body = content->litdata_body; - data->type = LITDATA; - pgp_memory_add(data->mem, data->data.litdata_body.data, - data->data.litdata_body.length); - return PGP_KEEP_MEMORY; - - case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY: - data->data.cleartext_body = content->cleartext_body; - data->type = SIGNED_CLEARTEXT; - pgp_memory_add(data->mem, data->data.cleartext_body.data, - data->data.cleartext_body.length); - return PGP_KEEP_MEMORY; - - case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - /* this gives us an pgp_hash_t struct */ - break; - - case PGP_PTAG_CT_SIGNATURE: /* V3 sigs */ - case PGP_PTAG_CT_SIGNATURE_FOOTER: /* V4 sigs */ - if (pgp_get_debug_level(__FILE__)) { - hexdump(io->outs, "hashed data", content->sig.info.v4_hashed, - content->sig.info.v4_hashlen); - hexdump(io->outs, "signer id", content->sig.info.signer_id, - sizeof(content->sig.info.signer_id)); - } - from = 0; - sigkey = NULL; - signer = pgp_getkeybyid(io, data->keyring, - content->sig.info.signer_id, &from, &sigkey, NULL, - 0, 0); /* check neither revocation nor expiry */ - if (!signer || !sigkey) { - PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER, - "%s", "Unknown Signer"); - if (!add_sig_to_list(&content->sig.info, - &data->result->unknown_sigs, - &data->result->unknownc)) { - PGP_ERROR_1(errors, PGP_E_V_UNKNOWN_SIGNER, - "%s", "Can't add unknown sig to list"); - } - break; - } - if (content->sig.info.birthtime_set) { - data->result->birthtime = content->sig.info.birthtime; - } - if (content->sig.info.duration_set) { - data->result->duration = content->sig.info.duration; - } - switch (content->sig.info.type) { - case PGP_SIG_BINARY: - case PGP_SIG_TEXT: - if (pgp_mem_len(data->mem) == 0){ - if(data->detachname) { - /* check we have seen some data */ - /* if not, need to read from detached name */ - (void) fprintf(io->errs, - "netpgp: assuming signed data in \"%s\"\n", - data->detachname); - data->mem = pgp_memory_new(); - pgp_mem_readfile(data->mem, data->detachname); - } - } - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "sig dump", (const uint8_t *)(const void *)&content->sig, - sizeof(content->sig)); - } - valid = check_binary_sig(pgp_mem_data(data->mem), - (const unsigned)pgp_mem_len(data->mem), - &content->sig, - sigkey); - break; - - default: - PGP_ERROR_1(errors, PGP_E_UNIMPLEMENTED, - "No Sig Verification type 0x%02x yet\n", - content->sig.info.type); - break; - - } - - if (valid) { - if (!add_sig_to_list(&content->sig.info, - &data->result->valid_sigs, - &data->result->validc)) { - PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, - "%s", "Can't add good sig to list"); - } - } else { - PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, - "%s", "Bad Signature"); - if (!add_sig_to_list(&content->sig.info, - &data->result->invalid_sigs, - &data->result->invalidc)) { - PGP_ERROR_1(errors, PGP_E_V_BAD_SIGNATURE, "%s", - "Can't add good sig to list"); - } - } - break; - - /* ignore these */ - case PGP_PARSER_PTAG: - case PGP_PTAG_CT_SIGNATURE_HEADER: - case PGP_PTAG_CT_ARMOUR_HEADER: - case PGP_PTAG_CT_ARMOUR_TRAILER: - case PGP_PTAG_CT_1_PASS_SIG: - break; - - case PGP_PARSER_PACKET_END: - break; - - default: - PGP_ERROR_1(errors, PGP_E_V_NO_SIGNATURE, "%s", "No signature"); - break; - } - return PGP_RELEASE_MEMORY; -} - -static char * -fmtsecs(int64_t n, char *buf, size_t size) -{ - if (n > 365 * 24 * 60 * 60) { - n /= (365 * 24 * 60 * 60); - (void) snprintf(buf, size, "%" PRId64 " year%s", n, (n == 1) ? "" : "s"); - return buf; - } - if (n > 30 * 24 * 60 * 60) { - n /= (30 * 24 * 60 * 60); - (void) snprintf(buf, size, "%" PRId64 " month%s", n, (n == 1) ? "" : "s"); - return buf; - } - if (n > 24 * 60 * 60) { - n /= (24 * 60 * 60); - (void) snprintf(buf, size, "%" PRId64 " day%s", n, (n == 1) ? "" : "s"); - return buf; - } - if (n > 60 * 60) { - n /= (60 * 60); - (void) snprintf(buf, size, "%" PRId64 " hour%s", n, (n == 1) ? "" : "s"); - return buf; - } - if (n > 60) { - n /= 60; - (void) snprintf(buf, size, "%" PRId64 " minute%s", n, (n == 1) ? "" : "s"); - return buf; - } - (void) snprintf(buf, size, "%" PRId64 " second%s", n, (n == 1) ? "" : "s"); - return buf; -} - -/** - * \ingroup HighLevel_Verify - * \brief Indicicates whether any errors were found - * \param result Validation result to check - * \return 0 if any invalid signatures or unknown signers - or no valid signatures; else 1 - */ -static unsigned -validate_result_status(FILE *errs, const char *f, pgp_validation_t *val) -{ - time_t now; - time_t t; - char buf[128]; - - now = time(NULL); - if (now < val->birthtime) { - /* signature is not valid yet! */ - if (f) { - (void) fprintf(errs, "\"%s\": ", f); - } else { - (void) fprintf(errs, "memory "); - } - (void) fprintf(errs, - "signature not valid until %.24s (%s)\n", - ctime(&val->birthtime), - fmtsecs((int64_t)(val->birthtime - now), buf, sizeof(buf))); - return 0; - } - if (val->duration != 0 && now > val->birthtime + val->duration) { - /* signature has expired */ - t = val->duration + val->birthtime; - if (f) { - (void) fprintf(errs, "\"%s\": ", f); - } else { - (void) fprintf(errs, "memory "); - } - (void) fprintf(errs, - "signature not valid after %.24s (%s ago)\n", - ctime(&t), - fmtsecs((int64_t)(now - t), buf, sizeof(buf))); - return 0; - } - return val->validc && !val->invalidc && !val->unknownc; -} - -typedef struct key_filter_cb_t{ - pgp_keyring_t *destpubring; - pgp_keyring_t *destsecring; - pgp_key_t *pubkey; - pgp_key_t *seckey; -} key_filter_cb_t; - -static pgp_cb_ret_t key_filter_cb ( - validate_key_cb_t *vdata, - const pgp_subpacket_t *sigpkt) -{ - pgp_key_t *pubkey; - pgp_key_t *seckey = NULL; - key_filter_cb_t *filter = vdata->on_valid_args; - - if(vdata->not_commited){ - - if((filter->pubkey = pgp_ensure_pubkey(filter->destpubring, - (vdata->type == PGP_PTAG_CT_PUBLIC_KEY) ? - &vdata->key.pubkey : - &vdata->key.seckey.pubkey, - vdata->pubkeyid))==NULL){ - return PGP_RELEASE_MEMORY; - } - - filter->seckey = NULL; - if (vdata->type == PGP_PTAG_CT_SECRET_KEY && filter->destsecring) { - if((filter->seckey = pgp_ensure_seckey( - filter->destsecring, - &vdata->key.seckey, - vdata->pubkeyid))==NULL){ - return PGP_RELEASE_MEMORY; - } - } - /* TODO get seckey by ID id even if given key is public - * in order to update uids an attributes from pubkey */ - } - - pubkey = filter->pubkey; - if(pubkey == NULL) - return PGP_RELEASE_MEMORY; - - if (vdata->type == PGP_PTAG_CT_SECRET_KEY) { - seckey = filter->seckey; - } - - switch(vdata->last_seen){ - case LS_PRIMARY: - - pgp_add_directsig(pubkey, sigpkt, &vdata->valid_sig_info); - - if (seckey) { - pgp_add_directsig(seckey, sigpkt, &vdata->valid_sig_info); - } - break; - case LS_ID: - - pgp_update_userid(pubkey, vdata->userid, sigpkt, &vdata->valid_sig_info); - if (seckey) { - pgp_update_userid(seckey, vdata->userid, sigpkt, &vdata->valid_sig_info); - } - - break; - case LS_ATTRIBUTE: - /* TODO */ - break; - case LS_SUBKEY: - pgp_update_subkey(pubkey, - vdata->type, &vdata->subkey, - sigpkt, &vdata->valid_sig_info); - if (seckey) { - pgp_update_subkey(seckey, - vdata->type, &vdata->subkey, - sigpkt, &vdata->valid_sig_info); - } - - break; - default: - break; - } - return PGP_RELEASE_MEMORY; -} - -#if 0 ////// -unsigned -pgp_filter_keys_fileread( - pgp_io_t *io, - pgp_keyring_t *destpubring, - pgp_keyring_t *destsecring, - pgp_keyring_t *certring, - const unsigned armour, - const char *filename) -{ - pgp_stream_t *stream; - validate_key_cb_t vdata; - key_filter_cb_t filter; - unsigned res = 1; - int fd; - - (void) memset(&vdata, 0x0, sizeof(vdata)); - vdata.result = NULL; - vdata.getpassphrase = NULL; - - (void) memset(&filter, 0x0, sizeof(filter)); - filter.destpubring = destpubring; - filter.destsecring = destsecring; - - fd = pgp_setup_file_read(io, - &stream,filename, - &vdata, - pgp_validate_key_cb, - 1); - - if (fd < 0) { - perror(filename); - return 0; - } - - pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED); - - if (armour) { - pgp_reader_push_dearmour(stream); - } - - vdata.keyring = certring; - - vdata.on_valid = &key_filter_cb; - vdata.on_valid_args = &filter; - - res = pgp_parse(stream, 0); - - validate_key_cb_free(&vdata); - - if (armour) { - pgp_reader_pop_dearmour(stream); - } - - (void)close(fd); - - pgp_stream_delete(stream); - - return res; -} -#endif - -unsigned -pgp_filter_keys_from_mem( - pgp_io_t *io, - pgp_keyring_t *destpubring, - pgp_keyring_t *destsecring, - pgp_keyring_t *certring, - const unsigned armour, - pgp_memory_t *mem) -{ - pgp_stream_t *stream; - validate_key_cb_t vdata; - key_filter_cb_t filter; - unsigned res; - - (void) memset(&vdata, 0x0, sizeof(vdata)); - vdata.result = NULL; - vdata.getpassphrase = NULL; - - (void) memset(&filter, 0x0, sizeof(filter)); - filter.destpubring = destpubring; - filter.destsecring = destsecring; - - //stream = pgp_new(sizeof(*stream)); -- Memory leak fixed by Delta Chat: not needed, stream is overwritten in pgp_setup_memory_read() - pgp_setup_memory_read(io, &stream, mem, &vdata, pgp_validate_key_cb, 1); - pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED); // the original code does not set PGP_PARSE_PARSED, however this seems to be a bug as this function was called before pgp_setup_memory_read() - as pgp_filter_keys_fileread() uses the same callback, I assume, PGP_PARSE_PARSED is the expected behaviour. - - if (armour) { - pgp_reader_push_dearmour(stream); - } - - vdata.keyring = certring; - - vdata.on_valid = &key_filter_cb; - vdata.on_valid_args = &filter; - - res = pgp_parse(stream, 0); - - validate_key_cb_free(&vdata); - - if (armour) { - pgp_reader_pop_dearmour(stream); - } - - /* don't call teardown_memory_read because memory was passed in */ - pgp_stream_delete(stream); - return res; -} - -/** - \ingroup HighLevel_Verify - \brief Frees validation result and associated memory - \param result Struct to be freed - \note Must be called after validation functions -*/ -void -pgp_validate_result_free(pgp_validation_t *result) -{ - if (result != NULL) { - if (result->valid_sigs) { - free_sig_info(result->valid_sigs); - } - if (result->invalid_sigs) { - free_sig_info(result->invalid_sigs); - } - if (result->unknown_sigs) { - free_sig_info(result->unknown_sigs); - } - free(result); - /* result = NULL; - XXX unnecessary */ - } -} - -/** - \ingroup HighLevel_Verify - \brief Verifies the signatures in a signed file - \param result Where to put the result - \param filename Name of file to be validated - \param armoured Treat file as armoured, if set - \param keyring Keyring to use - \return 1 if signatures validate successfully; - 0 if signatures fail or there are no signatures - \note After verification, result holds the details of all keys which - have passed, failed and not been recognised. - \note It is the caller's responsiblity to call - pgp_validate_result_free(result) after use. -*/ -#if 0 /////// -unsigned -pgp_validate_file(pgp_io_t *io, - pgp_validation_t *result, - const char *infile, - const char *outfile, - const int user_says_armoured, - const pgp_keyring_t *keyring) -{ - validate_data_cb_t validation; - pgp_stream_t *parse = NULL; - struct stat st; - const char *signame; - const int printerrors = 1; - unsigned ret; - char f[MAXPATHLEN]; - char *dataname; - int realarmour; - int outfd = 0; - int infd; - int cc; - - if (stat(infile, &st) < 0) { - (void) fprintf(io->errs, - "pgp_validate_file: can't open '%s'\n", infile); - return 0; - } - realarmour = user_says_armoured; - dataname = NULL; - signame = NULL; - cc = snprintf(f, sizeof(f), "%s", infile); - if (strcmp(&f[cc - 4], ".sig") == 0) { - /* we've been given a sigfile as infile */ - f[cc - 4] = 0x0; - /* set dataname to name of file which was signed */ - dataname = f; - signame = infile; - } else if (strcmp(&f[cc - 4], ".asc") == 0) { - /* we've been given an armored sigfile as infile */ - f[cc - 4] = 0x0; - /* set dataname to name of file which was signed */ - dataname = f; - signame = infile; - realarmour = 1; - } else { - signame = infile; - } - (void) memset(&validation, 0x0, sizeof(validation)); - infd = pgp_setup_file_read(io, &parse, signame, &validation, - validate_data_cb, 1); - if (infd < 0) { - return 0; - } - - if (dataname) { - validation.detachname = netpgp_strdup(dataname); - } - - /* Set verification reader and handling options */ - validation.result = result; - validation.keyring = keyring; - validation.mem = pgp_memory_new(); - pgp_memory_init(validation.mem, 128); - - if (realarmour) { - pgp_reader_push_dearmour(parse); - } - - /* Do the verification */ - pgp_parse(parse, !printerrors); - - /* Tidy up */ - if (realarmour) { - pgp_reader_pop_dearmour(parse); - } - pgp_teardown_file_read(parse, infd); - - ret = validate_result_status(io->errs, infile, result); - - /* this is triggered only for --cat output */ - if (outfile) { - /* need to send validated output somewhere */ - if (strcmp(outfile, "-") == 0) { - outfd = STDOUT_FILENO; - } else { - outfd = open(outfile, O_WRONLY | O_CREAT, 0666); - } - if (outfd < 0) { - /* even if the signature was good, we can't - * write the file, so send back a bad return - * code */ - ret = 0; - } else if (validate_result_status(io->errs, infile, result)) { - unsigned len; - char *cp; - int i; - - len = (unsigned)pgp_mem_len(validation.mem); - cp = pgp_mem_data(validation.mem); - for (i = 0 ; i < (int)len ; i += cc) { - cc = (int)write(outfd, &cp[i], (unsigned)(len - i)); - if (cc < 0) { - (void) fprintf(io->errs, - "netpgp: short write\n"); - ret = 0; - break; - } - } - if (strcmp(outfile, "-") != 0) { - (void) close(outfd); - } - } - } - pgp_memory_free(validation.mem); - return ret; -} -#endif ////// - -/** - \ingroup HighLevel_Verify - \brief Verifies the signatures in a pgp_memory_t struct - \param result Where to put the result - \param mem Memory to be validated - \param user_says_armoured Treat data as armoured, if set - \param keyring Keyring to use - \param detachmem detached memory (free done in this call if provided) - \return 1 if signature validates successfully; 0 if not - \note After verification, result holds the details of all keys which - have passed, failed and not been recognised. - \note It is the caller's responsiblity to call - pgp_validate_result_free(result) after use. -*/ -static inline unsigned -_pgp_validate_mem(pgp_io_t *io, - pgp_validation_t *result, - pgp_memory_t *mem, - pgp_memory_t **cat, - const int user_says_armoured, - const pgp_keyring_t *keyring, - pgp_memory_t *detachmem) -{ - validate_data_cb_t validation; - pgp_stream_t *stream = NULL; - const int printerrors = 1; - int realarmour; - - pgp_setup_memory_read(io, &stream, mem, &validation, validate_data_cb, 1); - - /* Set verification reader and handling options */ - (void) memset(&validation, 0x0, sizeof(validation)); - validation.result = result; - validation.keyring = keyring; - if (detachmem) { - validation.mem = detachmem; - }else{ - validation.mem = pgp_memory_new(); - pgp_memory_init(validation.mem, 128); - } - - if ((realarmour = user_says_armoured) != 0 || - strncmp(pgp_mem_data(mem), - "-----BEGIN PGP MESSAGE-----", 27) == 0) { - realarmour = 1; - } - if (realarmour) { - pgp_reader_push_dearmour(stream); - } - - /* Do the verification */ - pgp_parse(stream, !printerrors); - - /* Tidy up */ - if (realarmour) { - pgp_reader_pop_dearmour(stream); - } - pgp_teardown_memory_read(stream, mem); - - /* this is triggered only for --cat output */ - if (cat) { - /* need to send validated output somewhere */ - *cat = validation.mem; - } else { - pgp_memory_free(validation.mem); - } - - return validate_result_status(io->errs, NULL, result); -} - -unsigned -pgp_validate_mem(pgp_io_t *io, - pgp_validation_t *result, - pgp_memory_t *mem, - pgp_memory_t **cat, - const int user_says_armoured, - const pgp_keyring_t *keyring) -{ - return _pgp_validate_mem(io, - result, - mem, - cat, - user_says_armoured, - keyring, - NULL); -} - -unsigned -pgp_validate_mem_detached(pgp_io_t *io, - pgp_validation_t *result, - pgp_memory_t *mem, - pgp_memory_t **cat, - const int user_says_armoured, - const pgp_keyring_t *keyring, - pgp_memory_t *detachmem) -{ - return _pgp_validate_mem(io, - result, - mem, - cat, - user_says_armoured, - keyring, - detachmem); -} - diff --git a/netpgp/writer.c b/netpgp/writer.c deleted file mode 100644 index 69e04f107f71703bb4f70f1405bcc4fb147409c0..0000000000000000000000000000000000000000 --- a/netpgp/writer.c +++ /dev/null @@ -1,1895 +0,0 @@ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Alistair Crooks (agc@NetBSD.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * This file contains the base functions used by the writers. - */ -#include "netpgp/config-netpgp.h" - -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - -#if defined(__NetBSD__) -__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD$"); -#endif - -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_OPENSSL_CAST_H -#include <openssl/cast.h> -#endif - -#include "netpgp/create.h" -#include "netpgp/writer.h" -#include "netpgp/keyring.h" -#include "netpgp/signature.h" -#include "netpgp/packet.h" -#include "netpgp/packet-parse.h" -#include "netpgp/readerwriter.h" -#include "netpgp/memory.h" -#include "netpgp/netpgpdefs.h" -#include "netpgp/version.h" -#include "netpgp/netpgpdigest.h" - - -/* - * return 1 if OK, otherwise 0 - */ -static unsigned -base_write(pgp_output_t *out, const void *src, unsigned len) -{ - return out->writer.writer(src, len, &out->errors, &out->writer); -} - -/** - * \ingroup Core_WritePackets - * - * \param src - * \param len - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write(pgp_output_t *output, const void *src, unsigned len) -{ - return base_write(output, src, len); -} - -/** - * \ingroup Core_WritePackets - * \param n - * \param len - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_scalar(pgp_output_t *output, unsigned n, unsigned len) -{ - uint8_t c; - - while (len-- > 0) { - c = n >> (len * 8); - if (!base_write(output, &c, 1)) { - return 0; - } - } - return 1; -} - -/** - * \ingroup Core_WritePackets - * \param bn - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_mpi(pgp_output_t *output, const BIGNUM *bn) -{ - unsigned bits; - uint8_t buf[NETPGP_BUFSIZ]; - - bits = (unsigned)BN_num_bits(bn); - if (bits > 65535) { - (void) fprintf(stderr, "pgp_write_mpi: too large %u\n", bits); - return 0; - } - BN_bn2bin(bn, buf); - return pgp_write_scalar(output, bits, 2) && - pgp_write(output, buf, (bits + 7) / 8); -} - -/** - * \ingroup Core_WritePackets - * \param tag - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_ptag(pgp_output_t *output, pgp_content_enum tag) -{ - uint8_t c; - - c = tag | PGP_PTAG_ALWAYS_SET | PGP_PTAG_NEW_FORMAT; - return base_write(output, &c, 1); -} - -/** - * \ingroup Core_WritePackets - * \param len - * \param output - * \return 1 if OK, otherwise 0 - */ - -unsigned -pgp_write_length(pgp_output_t *output, unsigned len) -{ - uint8_t c[2]; - - if (len < 192) { - c[0] = len; - return base_write(output, c, 1); - } - if (len < 8192 + 192) { - c[0] = ((len - 192) >> 8) + 192; - c[1] = (len - 192) % 256; - return base_write(output, c, 2); - } - return pgp_write_scalar(output, 0xff, 1) && - pgp_write_scalar(output, len, 4); -} - -/* - * Note that we finalise from the top down, so we don't use writers below - * that have already been finalised - */ -unsigned -pgp_writer_info_finalise(pgp_error_t **errors, pgp_writer_t *writer) -{ - unsigned ret = 1; - - if (writer->finaliser) { - ret = writer->finaliser(errors, writer); - writer->finaliser = NULL; - } - if (writer->next && !pgp_writer_info_finalise(errors, writer->next)) { - writer->finaliser = NULL; - return 0; - } - return ret; -} - -void -pgp_writer_info_delete(pgp_writer_t *writer) -{ - /* we should have finalised before deleting */ - if (writer->finaliser) { - (void) fprintf(stderr, "pgp_writer_info_delete: not done\n"); - return; - } - if (writer->next) { - pgp_writer_info_delete(writer->next); - free(writer->next); - writer->next = NULL; - } - if (writer->destroyer) { - writer->destroyer(writer); - writer->destroyer = NULL; - } - writer->writer = NULL; -} - -/** - * \ingroup Core_Writers - * - * Set a writer in output. There should not be another writer set. - * - * \param output The output structure - * \param writer - * \param finaliser - * \param destroyer - * \param arg The argument for the writer and destroyer - */ -void -pgp_writer_set(pgp_output_t *output, - pgp_writer_func_t *writer, - pgp_writer_finaliser_t *finaliser, - pgp_writer_destroyer_t *destroyer, - void *arg) -{ - if (output->writer.writer) { - (void) fprintf(stderr, "pgp_writer_set: already set\n"); - } else { - output->writer.writer = writer; - output->writer.finaliser = finaliser; - output->writer.destroyer = destroyer; - output->writer.arg = arg; - } -} - -/** - * \ingroup Core_Writers - * - * Push a writer in output. There must already be another writer set. - * - * \param output The output structure - * \param writer - * \param finaliser - * \param destroyer - * \param arg The argument for the writer and destroyer - */ -void -pgp_writer_push(pgp_output_t *output, - pgp_writer_func_t *writer, - pgp_writer_finaliser_t *finaliser, - pgp_writer_destroyer_t *destroyer, - void *arg) -{ - pgp_writer_t *copy; - - if (output->writer.writer == NULL) { - (void) fprintf(stderr, "pgp_writer_push: no orig writer\n"); - } else { - if ((copy = calloc(1, sizeof(*copy))) == NULL) { - (void) fprintf(stderr, "pgp_writer_push: bad alloc\n"); - return; /* TODO return error */ - } - *copy = output->writer; - output->writer.next = copy; - - output->writer.writer = writer; - output->writer.finaliser = finaliser; - output->writer.destroyer = destroyer; - output->writer.arg = arg; - } -} - -void -pgp_writer_pop(pgp_output_t *output) -{ - pgp_writer_t *next; - - /* Make sure the finaliser has been called. */ - if (output->writer.finaliser) { - (void) fprintf(stderr, - "pgp_writer_pop: finaliser not called\n"); - } else if (output->writer.next == NULL) { - (void) fprintf(stderr, - "pgp_writer_pop: not a stacked writer\n"); - } else { - if (output->writer.destroyer) { - output->writer.destroyer(&output->writer); - } - next = output->writer.next; - output->writer = *next; - free(next); - } -} - -/** - * \ingroup Core_Writers - * - * Close the writer currently set in output. - * - * \param output The output structure - */ -unsigned -pgp_writer_close(pgp_output_t *output) -{ - unsigned ret; - - ret = pgp_writer_info_finalise(&output->errors, &output->writer); - pgp_writer_info_delete(&output->writer); - return ret; -} - -/** - * \ingroup Core_Writers - * - * Get the arg supplied to pgp_createinfo_set_writer(). - * - * \param writer The writer_info structure - * \return The arg - */ -void * -pgp_writer_get_arg(pgp_writer_t *writer) -{ - return writer->arg; -} - -/** - * \ingroup Core_Writers - * - * Write to the next writer down in the stack. - * - * \param src The data to write. - * \param len The length of src. - * \param errors A place to store errors. - * \param writer The writer_info structure. - * \return Success - if 0, then errors should contain the error. - */ -static unsigned -stacked_write(pgp_writer_t *writer, const void *src, unsigned len, - pgp_error_t ** errors) -{ - return writer->next->writer(src, len, errors, writer->next); -} - -/** - * \ingroup Core_Writers - * - * Free the arg. Many writers just have a calloc()ed lump of storage, this - * function releases it. - * - * \param writer the info structure. - */ -static void -generic_destroyer(pgp_writer_t *writer) -{ - free(pgp_writer_get_arg(writer)); -} - -/** - * \ingroup Core_Writers - * - * A writer that just writes to the next one down. Useful for when you - * want to insert just a finaliser into the stack. - */ -unsigned -pgp_writer_passthrough(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - return stacked_write(writer, src, len, errors); -} - -/**************************************************************************/ - -/** - * \struct dashesc_t - */ -typedef struct { - unsigned seen_nl:1; - unsigned seen_cr:1; - pgp_create_sig_t *sig; - pgp_memory_t *trailing; -} dashesc_t; - -static unsigned -dash_esc_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - dashesc_t *dash = pgp_writer_get_arg(writer); - unsigned n; - - if (pgp_get_debug_level(__FILE__)) { - unsigned i = 0; - - (void) fprintf(stderr, "dash_esc_writer writing %u:\n", len); - for (i = 0; i < len; i++) { - fprintf(stderr, "0x%02x ", src[i]); - if (((i + 1) % 16) == 0) { - (void) fprintf(stderr, "\n"); - } else if (((i + 1) % 8) == 0) { - (void) fprintf(stderr, " "); - } - } - (void) fprintf(stderr, "\n"); - } - /* XXX: make this efficient */ - for (n = 0; n < len; ++n) { - unsigned l; - - if (dash->seen_nl) { - if (src[n] == '-' && - !stacked_write(writer, "- ", 2, errors)) { - return 0; - } - dash->seen_nl = 0; - } - dash->seen_nl = src[n] == '\n'; - - if (dash->seen_nl && !dash->seen_cr) { - if (!stacked_write(writer, "\r", 1, errors)) { - return 0; - } - pgp_sig_add_data(dash->sig, "\r", 1); - } - dash->seen_cr = src[n] == '\r'; - - if (!stacked_write(writer, &src[n], 1, errors)) { - return 0; - } - - /* trailing whitespace isn't included in the signature */ - if (src[n] == ' ' || src[n] == '\t') { - pgp_memory_add(dash->trailing, &src[n], 1); - } else { - if ((l = (unsigned)pgp_mem_len(dash->trailing)) != 0) { - if (!dash->seen_nl && !dash->seen_cr) { - pgp_sig_add_data(dash->sig, - pgp_mem_data(dash->trailing), l); - } - pgp_memory_clear(dash->trailing); - } - pgp_sig_add_data(dash->sig, &src[n], 1); - } - } - return 1; -} - -/** - * \param writer - */ -static void -dash_escaped_destroyer(pgp_writer_t *writer) -{ - dashesc_t *dash; - - dash = pgp_writer_get_arg(writer); - pgp_memory_free(dash->trailing); - free(dash); -} - -/** - * \ingroup Core_WritersNext - * \brief Push Clearsigned Writer onto stack - * \param output - * \param sig - */ -unsigned -pgp_writer_push_clearsigned(pgp_output_t *output, pgp_create_sig_t *sig) -{ - static const char header[] = - "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "; - const char *hash; - dashesc_t *dash; - unsigned ret; - - hash = pgp_text_from_hash(pgp_sig_get_hash(sig)); - if ((dash = calloc(1, sizeof(*dash))) == NULL) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", "Bad alloc"); - return 0; - } - ret = (pgp_write(output, header, (unsigned)(sizeof(header) - 1)) && - pgp_write(output, hash, (unsigned)strlen(hash)) && - pgp_write(output, "\r\n\r\n", 4)); - - if (ret == 0) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", - "Error pushing clearsigned header"); - free(dash); - return ret; - } - dash->seen_nl = 1; - dash->sig = sig; - dash->trailing = pgp_memory_new(); - pgp_writer_push(output, dash_esc_writer, NULL, - dash_escaped_destroyer, dash); - return ret; -} - - -/** - * \struct base64_t - */ -typedef struct { - unsigned pos; - uint8_t t; - unsigned checksum; -} base64_t; - -static const char b64map[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static unsigned -base64_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - base64_t *base64; - unsigned n; - - base64 = pgp_writer_get_arg(writer); - for (n = 0; n < len;) { - base64->checksum = pgp_crc24(base64->checksum, src[n]); - if (base64->pos == 0) { - /* XXXXXX00 00000000 00000000 */ - if (!stacked_write(writer, - &b64map[(unsigned)src[n] >> 2], - 1, errors)) { - return 0; - } - - /* 000000XX xxxx0000 00000000 */ - base64->t = (src[n++] & 3) << 4; - base64->pos = 1; - } else if (base64->pos == 1) { - /* 000000xx XXXX0000 00000000 */ - base64->t += (unsigned)src[n] >> 4; - if (!stacked_write(writer, &b64map[base64->t], 1, - errors)) { - return 0; - } - - /* 00000000 0000XXXX xx000000 */ - base64->t = (src[n++] & 0xf) << 2; - base64->pos = 2; - } else if (base64->pos == 2) { - /* 00000000 0000xxxx XX000000 */ - base64->t += (unsigned)src[n] >> 6; - if (!stacked_write(writer, &b64map[base64->t], 1, - errors)) { - return 0; - } - - /* 00000000 00000000 00XXXXXX */ - if (!stacked_write(writer, - &b64map[src[n++] & 0x3f], 1, errors)) { - return 0; - } - - base64->pos = 0; - } - } - - return 1; -} - -static unsigned -sig_finaliser(pgp_error_t **errors, pgp_writer_t *writer) -{ - static const char trail[] = "\r\n-----END PGP SIGNATURE-----\r\n"; - base64_t *base64; - uint8_t c[3]; - - base64 = pgp_writer_get_arg(writer); - if (base64->pos) { - if (!stacked_write(writer, &b64map[base64->t], 1, errors)) { - return 0; - } - if (base64->pos == 1 && - !stacked_write(writer, "==", 2, errors)) { - return 0; - } - if (base64->pos == 2 && - !stacked_write(writer, "=", 1, errors)) { - return 0; - } - } - /* Ready for the checksum */ - if (!stacked_write(writer, "\r\n=", 3, errors)) { - return 0; - } - - base64->pos = 0; /* get ready to write the checksum */ - - c[0] = base64->checksum >> 16; - c[1] = base64->checksum >> 8; - c[2] = base64->checksum; - /* push the checksum through our own writer */ - if (!base64_writer(c, 3, errors, writer)) { - return 0; - } - - return stacked_write(writer, trail, (unsigned)(sizeof(trail) - 1), errors); -} - -/** - * \struct linebreak_t - */ -typedef struct { - unsigned pos; -} linebreak_t; - -#define BREAKPOS 76 - -static unsigned -linebreak_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - linebreak_t *linebreak; - unsigned n; - - linebreak = pgp_writer_get_arg(writer); - for (n = 0; n < len; ++n, ++linebreak->pos) { - if (src[n] == '\r' || src[n] == '\n') { - linebreak->pos = 0; - } - if (linebreak->pos == BREAKPOS) { - if (!stacked_write(writer, "\r\n", 2, errors)) { - return 0; - } - linebreak->pos = 0; - } - if (!stacked_write(writer, &src[n], 1, errors)) { - return 0; - } - } - - return 1; -} - -/** - * \ingroup Core_WritersNext - * \brief Push armoured signature on stack - * \param output - */ -unsigned -pgp_writer_use_armored_sig(pgp_output_t *output) -{ - static const char header[] = - "\r\n-----BEGIN PGP SIGNATURE-----\r\nVersion: " - NETPGP_VERSION_STRING - "\r\n\r\n"; - linebreak_t *linebreak; - base64_t *base64; - - pgp_writer_pop(output); - if (pgp_write(output, header, (unsigned)(sizeof(header) - 1)) == 0) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", - "Error switching to armoured signature"); - return 0; - } - if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) { - PGP_ERROR_1(&output->errors, PGP_E_W, "%s", - "pgp_writer_use_armored_sig: Bad alloc"); - return 0; - } - pgp_writer_push(output, linebreak_writer, NULL, - generic_destroyer, - linebreak); - base64 = calloc(1, sizeof(*base64)); - if (!base64) { - PGP_MEMORY_ERROR(&output->errors); - return 0; - } - base64->checksum = CRC24_INIT; - pgp_writer_push(output, base64_writer, sig_finaliser, - generic_destroyer, base64); - return 1; -} - -static unsigned -armoured_message_finaliser(pgp_error_t **errors, pgp_writer_t *writer) -{ - /* TODO: This is same as sig_finaliser apart from trailer. */ - static const char trailer[] = - "\r\n-----END PGP MESSAGE-----\r\n"; - base64_t *base64; - uint8_t c[3]; - - base64 = pgp_writer_get_arg(writer); - if (base64->pos) { - if (!stacked_write(writer, &b64map[base64->t], 1, errors)) { - return 0; - } - if (base64->pos == 1 && - !stacked_write(writer, "==", 2, errors)) { - return 0; - } - if (base64->pos == 2 && - !stacked_write(writer, "=", 1, errors)) { - return 0; - } - } - /* Ready for the checksum */ - if (!stacked_write(writer, "\r\n=", 3, errors)) { - return 0; - } - - base64->pos = 0; /* get ready to write the checksum */ - - c[0] = base64->checksum >> 16; - c[1] = base64->checksum >> 8; - c[2] = base64->checksum; - /* push the checksum through our own writer */ - if (!base64_writer(c, 3, errors, writer)) { - return 0; - } - - return stacked_write(writer, trailer, (unsigned)strlen(trailer), errors); -} - -/** - \ingroup Core_WritersNext - \brief Write a PGP MESSAGE - \todo replace with generic function -*/ -void -pgp_writer_push_armor_msg(pgp_output_t *output) -{ - static const char header[] = "-----BEGIN PGP MESSAGE-----\r\n"; - linebreak_t *linebreak; - base64_t *base64; - - pgp_write(output, header, (unsigned)(sizeof(header) - 1)); - pgp_write(output, "\r\n", 2); - if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) { - (void) fprintf(stderr, - "pgp_writer_push_armor_msg: bad lb alloc\n"); - return; - } - pgp_writer_push(output, linebreak_writer, NULL, - generic_destroyer, - linebreak); - if ((base64 = calloc(1, sizeof(*base64))) == NULL) { - (void) fprintf(stderr, - "pgp_writer_push_armor_msg: bad alloc\n"); - return; - } - base64->checksum = CRC24_INIT; - pgp_writer_push(output, base64_writer, - armoured_message_finaliser, generic_destroyer, - base64); -} - -#if 0 ////// -static unsigned -armoured_finaliser(pgp_armor_type_t type, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - static const char tail_pubkey[] = - "\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n"; - static const char tail_private_key[] = - "\r\n-----END PGP PRIVATE KEY BLOCK-----\r\n"; - const char *tail = NULL; - unsigned tailsize = 0; - base64_t *base64; - uint8_t c[3]; - - switch (type) { - case PGP_PGP_PUBLIC_KEY_BLOCK: - tail = tail_pubkey; - tailsize = sizeof(tail_pubkey) - 1; - break; - - case PGP_PGP_PRIVATE_KEY_BLOCK: - tail = tail_private_key; - tailsize = sizeof(tail_private_key) - 1; - break; - - default: - (void) fprintf(stderr, "armoured_finaliser: unusual type\n"); - return 0; - } - base64 = pgp_writer_get_arg(writer); - if (base64->pos) { - if (!stacked_write(writer, &b64map[base64->t], 1, - errors)) { - return 0; - } - if (base64->pos == 1 && !stacked_write(writer, "==", 2, - errors)) { - return 0; - } - if (base64->pos == 2 && !stacked_write(writer, "=", 1, - errors)) { - return 0; - } - } - /* Ready for the checksum */ - if (!stacked_write(writer, "\r\n=", 3, errors)) { - return 0; - } - base64->pos = 0; /* get ready to write the checksum */ - c[0] = base64->checksum >> 16; - c[1] = base64->checksum >> 8; - c[2] = base64->checksum; - /* push the checksum through our own writer */ - if (!base64_writer(c, 3, errors, writer)) { - return 0; - } - return stacked_write(writer, tail, tailsize, errors); -} -#endif ////// - -#if 0 ////// -static unsigned -armored_pubkey_fini(pgp_error_t **errors, pgp_writer_t *writer) -{ - return armoured_finaliser(PGP_PGP_PUBLIC_KEY_BLOCK, errors, writer); -} -#endif ////// - -#if 0 ////// -static unsigned -armored_privkey_fini(pgp_error_t **errors, pgp_writer_t *writer) -{ - return armoured_finaliser(PGP_PGP_PRIVATE_KEY_BLOCK, errors, writer); -} -#endif ////// - -/* \todo use this for other armoured types */ -/** - \ingroup Core_WritersNext - \brief Push Armoured Writer on stack (generic) -*/ -#if 0 ////// -void -pgp_writer_push_armoured(pgp_output_t *output, pgp_armor_type_t type) -{ - static char hdr_pubkey[] = - "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: " - NETPGP_VERSION_STRING - "\r\n\r\n"; - static char hdr_private_key[] = - "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\nVersion: " - NETPGP_VERSION_STRING - "\r\n\r\n"; - unsigned hdrsize = 0; - unsigned (*finaliser) (pgp_error_t **, pgp_writer_t *); - base64_t *base64; - linebreak_t *linebreak; - char *header = NULL; - - finaliser = NULL; - switch (type) { - case PGP_PGP_PUBLIC_KEY_BLOCK: - header = hdr_pubkey; - hdrsize = sizeof(hdr_pubkey) - 1; - finaliser = armored_pubkey_fini; - break; - - case PGP_PGP_PRIVATE_KEY_BLOCK: - header = hdr_private_key; - hdrsize = sizeof(hdr_private_key) - 1; - finaliser = armored_privkey_fini; - break; - - default: - (void) fprintf(stderr, - "pgp_writer_push_armoured: unusual type\n"); - return; - } - if ((linebreak = calloc(1, sizeof(*linebreak))) == NULL) { - (void) fprintf(stderr, - "pgp_writer_push_armoured: bad alloc\n"); - return; - } - pgp_write(output, header, hdrsize); - pgp_writer_push(output, linebreak_writer, NULL, - generic_destroyer, - linebreak); - if ((base64 = calloc(1, sizeof(*base64))) == NULL) { - (void) fprintf(stderr, - "pgp_writer_push_armoured: bad alloc\n"); - free(linebreak); - return; - } - base64->checksum = CRC24_INIT; - pgp_writer_push(output, base64_writer, finaliser, - generic_destroyer, base64); -} -#endif ////// - -/**************************************************************************/ - -typedef struct { - pgp_crypt_t *crypt; - int free_crypt; -} crypt_t; - -/* - * This writer simply takes plaintext as input, - * encrypts it with the given key - * and outputs the resulting encrypted text - */ -static unsigned -encrypt_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ -#define BUFSZ 1024 /* arbitrary number */ - uint8_t encbuf[BUFSZ]; - unsigned remaining; - unsigned done = 0; - crypt_t *pgp_encrypt; - - remaining = len; - pgp_encrypt = (crypt_t *) pgp_writer_get_arg(writer); - if (!pgp_is_sa_supported(pgp_encrypt->crypt->alg)) { - (void) fprintf(stderr, "encrypt_writer: not supported\n"); - return 0; - } - while (remaining > 0) { - unsigned size = (remaining < BUFSZ) ? remaining : BUFSZ; - - /* memcpy(buf,src,size); // \todo copy needed here? */ - pgp_encrypt->crypt->cfb_encrypt(pgp_encrypt->crypt, encbuf, - src + done, size); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "unencrypted", &src[done], 16); - hexdump(stderr, "encrypted", encbuf, 16); - } - if (!stacked_write(writer, encbuf, size, errors)) { - if (pgp_get_debug_level(__FILE__)) { - fprintf(stderr, - "encrypted_writer: stacked write\n"); - } - return 0; - } - remaining -= size; - done += size; - } - - return 1; -} - -static void -encrypt_destroyer(pgp_writer_t *writer) -{ - crypt_t *pgp_encrypt; - - pgp_encrypt = (crypt_t *) pgp_writer_get_arg(writer); - if (pgp_encrypt->free_crypt) { - free(pgp_encrypt->crypt); - } - free(pgp_encrypt); -} - -/** -\ingroup Core_WritersNext -\brief Push Encrypted Writer onto stack (create SE packets) -*/ -void -pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt) -{ - /* Create encrypt to be used with this writer */ - /* Remember to free this in the destroyer */ - crypt_t *pgp_encrypt; - - if ((pgp_encrypt = calloc(1, sizeof(*pgp_encrypt))) == NULL) { - (void) fprintf(stderr, "pgp_push_enc_crypt: bad alloc\n"); - } else { - /* Setup the encrypt */ - pgp_encrypt->crypt = pgp_crypt; - pgp_encrypt->free_crypt = 0; - /* And push writer on stack */ - pgp_writer_push(output, encrypt_writer, NULL, - encrypt_destroyer, pgp_encrypt); - } -} - -/**************************************************************************/ - -typedef struct { - pgp_crypt_t *crypt; - unsigned raw; -} encrypt_se_ip_t; - -static unsigned encrypt_se_ip_writer(const uint8_t *, - unsigned, - pgp_error_t **, - pgp_writer_t *); -static void encrypt_se_ip_destroyer(pgp_writer_t *); - -/* */ - -/** -\ingroup Core_WritersNext -\brief Push Encrypted SE IP Writer onto stack -*/ -int -pgp_push_enc_se_ip(pgp_output_t *output, const pgp_keyring_t *pubkeys, const char *cipher, unsigned raw) -{ - pgp_pk_sesskey_t *initial_sesskey = NULL; - pgp_pk_sesskey_t *encrypted_pk_sesskey; - encrypt_se_ip_t *se_ip; - pgp_crypt_t *encrypted; - uint8_t *iv; - unsigned n; - - if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) { - (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n"); - return 0; - } - - for (n = 0; n < pubkeys->keyc; ++n) { - /* Create and write encrypted PK session key */ - if ((encrypted_pk_sesskey = - pgp_create_pk_sesskey(&pubkeys->keys[n], - cipher, initial_sesskey)) == NULL) { - (void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n"); - free(se_ip); - return 0; - } - - if (initial_sesskey == NULL) { - initial_sesskey = encrypted_pk_sesskey; - } - - pgp_write_pk_sesskey(output, encrypted_pk_sesskey); - - if(encrypted_pk_sesskey != initial_sesskey){ - free(encrypted_pk_sesskey); - } - } - - if (initial_sesskey == NULL) { - (void) fprintf(stderr, "pgp_push_enc_se_ip: no sesskey\n"); - free(se_ip); - return 0; - } - - /* Setup the se_ip */ - if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) { - free(se_ip); - (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n"); - return 0; - } - pgp_crypt_any(encrypted, initial_sesskey->symm_alg); - if ((iv = calloc(1, encrypted->blocksize)) == NULL) { - free(se_ip); - free(encrypted); - (void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n"); - return 0; - } - encrypted->set_iv(encrypted, iv); - encrypted->set_crypt_key(encrypted, &initial_sesskey->key[0]); - pgp_encrypt_init(encrypted); - - se_ip->crypt = encrypted; - se_ip->raw = raw; - - /* And push writer on stack */ - pgp_writer_push(output, encrypt_se_ip_writer, NULL, - encrypt_se_ip_destroyer, se_ip); - /* tidy up */ - free(initial_sesskey); - free(iv); - return 1; -} - -static unsigned -encrypt_se_ip_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - const unsigned bufsz = 128; - encrypt_se_ip_t *se_ip = pgp_writer_get_arg(writer); - pgp_output_t *litoutput; - pgp_output_t *zoutput; - pgp_output_t *output; - pgp_memory_t *litmem; - pgp_memory_t *zmem; - pgp_memory_t *localmem; - unsigned ret = 1; - - const uint8_t *zsrc; - unsigned zsrclen; - - pgp_setup_memory_write(&litoutput, &litmem, bufsz); - pgp_setup_memory_write(&zoutput, &zmem, bufsz); - pgp_setup_memory_write(&output, &localmem, bufsz); - - if (!se_ip->raw) { - /* create literal data packet from source data */ - pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY); - if (pgp_mem_len(litmem) <= len) { - (void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n"); - return 0; - } - zsrc = pgp_mem_data(litmem); - zsrclen = (unsigned)pgp_mem_len(litmem); - }else{ - zsrc = src; - zsrclen = len; - } - - /* create compressed packet from literal data packet */ - pgp_writez(zoutput, zsrc, zsrclen); - - /* create SE IP packet set from this compressed literal data */ - pgp_write_se_ip_pktset(output, pgp_mem_data(zmem), - (unsigned)pgp_mem_len(zmem), - se_ip->crypt); - if (pgp_mem_len(localmem) <= pgp_mem_len(zmem)) { - (void) fprintf(stderr, - "encrypt_se_ip_writer: bad comp len\n"); - return 0; - } - - /* now write memory to next writer */ - ret = stacked_write(writer, pgp_mem_data(localmem), - (unsigned)pgp_mem_len(localmem), errors); - - pgp_memory_free(localmem); - pgp_memory_free(zmem); - pgp_memory_free(litmem); - - return ret; -} - -static void -encrypt_se_ip_destroyer(pgp_writer_t *writer) -{ - encrypt_se_ip_t *se_ip; - - se_ip = pgp_writer_get_arg(writer); - free(se_ip->crypt); - free(se_ip); -} - -unsigned -pgp_write_se_ip_pktset(pgp_output_t *output, - const uint8_t *data, - const unsigned len, - pgp_crypt_t *crypted) -{ - pgp_output_t *mdcoutput; - pgp_memory_t *mdc; - uint8_t hashed[PGP_SHA1_HASH_SIZE]; - uint8_t *preamble; - const size_t mdcsize = 1 + 1 + PGP_SHA1_HASH_SIZE; - size_t preamblesize; - size_t bufsize; - - preamblesize = crypted->blocksize + 2; - if ((preamble = calloc(1, preamblesize)) == NULL) { - (void) fprintf(stderr, "pgp_write_se_ip_pktset: bad alloc\n"); - return 0; - } - bufsize = preamblesize + len + mdcsize; - - if (!pgp_write_ptag(output, PGP_PTAG_CT_SE_IP_DATA) || - !pgp_write_length(output, (unsigned)(1 + bufsize)) || - !pgp_write_scalar(output, PGP_SE_IP_DATA_VERSION, 1)) { - free(preamble); - return 0; - } - pgp_random(preamble, crypted->blocksize); - preamble[crypted->blocksize] = preamble[crypted->blocksize - 2]; - preamble[crypted->blocksize + 1] = preamble[crypted->blocksize - 1]; - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "preamble", preamble, preamblesize); - } - - /* now construct MDC packet and add to the end of the buffer */ - pgp_setup_memory_write(&mdcoutput, &mdc, mdcsize); - pgp_calc_mdc_hash(preamble, preamblesize, data, len, hashed); - pgp_write_mdc(mdcoutput, hashed); - - if (pgp_get_debug_level(__FILE__)) { - hexdump(stderr, "plaintext", data, len); - hexdump(stderr, "mdc", pgp_mem_data(mdc), PGP_SHA1_HASH_SIZE + 1 + 1); - } - - /* and write it out */ - pgp_push_enc_crypt(output, crypted); - if (pgp_get_debug_level(__FILE__)) { - (void) fprintf(stderr, - "writing %" PRIsize "u + %u + %" PRIsize "u\n", - preamblesize, len, pgp_mem_len(mdc)); - } - if (!pgp_write(output, preamble, (unsigned)preamblesize) || - !pgp_write(output, data, len) || - !pgp_write(output, pgp_mem_data(mdc), (unsigned)pgp_mem_len(mdc))) { - /* \todo fix cleanup here and in old code functions */ - return 0; - } - - pgp_writer_pop(output); - - /* cleanup */ - pgp_teardown_memory_write(mdcoutput, mdc); - free(preamble); - - return 1; -} - -typedef struct { - int fd; -} writer_fd_t; - -static unsigned -fd_writer(const uint8_t *src, unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - writer_fd_t *writerfd; - int n; - - writerfd = pgp_writer_get_arg(writer); - n = (int)write(writerfd->fd, src, len); - if (n == -1) { - PGP_SYSTEM_ERROR_1(errors, PGP_E_W_WRITE_FAILED, "write", - "file descriptor %d", writerfd->fd); - return 0; - } - if ((unsigned) n != len) { - PGP_ERROR_1(errors, PGP_E_W_WRITE_TOO_SHORT, - "file descriptor %d", writerfd->fd); - return 0; - } - return 1; -} - -static void -writer_fd_destroyer(pgp_writer_t *writer) -{ - free(pgp_writer_get_arg(writer)); -} - -/** - * \ingroup Core_WritersFirst - * \brief Write to a File - * - * Set the writer in output to be a stock writer that writes to a file - * descriptor. If another writer has already been set, then that is - * first destroyed. - * - * \param output The output structure - * \param fd The file descriptor - * - */ - -void -pgp_writer_set_fd(pgp_output_t *output, int fd) -{ - writer_fd_t *writer; - - if ((writer = calloc(1, sizeof(*writer))) == NULL) { - (void) fprintf(stderr, "pgp_writer_set_fd: bad alloc\n"); - } else { - writer->fd = fd; - pgp_writer_set(output, fd_writer, NULL, writer_fd_destroyer, writer); - } -} - -static unsigned -memory_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - pgp_memory_t *mem; - - __PGP_USED(errors); - mem = pgp_writer_get_arg(writer); - pgp_memory_add(mem, src, len); - return 1; -} - -/** - * \ingroup Core_WritersFirst - * \brief Write to memory - * - * Set a memory writer. - * - * \param output The output structure - * \param mem The memory structure - * \note It is the caller's responsiblity to call pgp_memory_free(mem) - * \sa pgp_memory_free() - */ - -void -pgp_writer_set_memory(pgp_output_t *output, pgp_memory_t *mem) -{ - pgp_writer_set(output, memory_writer, NULL, NULL, mem); -} - -/**************************************************************************/ - -typedef struct { - pgp_hash_alg_t hash_alg; - pgp_hash_t hash; - uint8_t *hashed; -} skey_checksum_t; - -static unsigned -skey_checksum_writer(const uint8_t *src, - const unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - skey_checksum_t *sum; - unsigned ret = 1; - - sum = pgp_writer_get_arg(writer); - /* add contents to hash */ - sum->hash.add(&sum->hash, src, len); - /* write to next stacked writer */ - ret = stacked_write(writer, src, len, errors); - /* tidy up and return */ - return ret; -} - -static unsigned -skey_checksum_finaliser(pgp_error_t **errors, pgp_writer_t *writer) -{ - skey_checksum_t *sum; - - sum = pgp_writer_get_arg(writer); - if (errors && *errors) { - printf("errors in skey_checksum_finaliser\n"); - } - (*sum->hash.finish)(&sum->hash, sum->hashed); - return 1; -} - -static void -skey_checksum_destroyer(pgp_writer_t *writer) -{ - skey_checksum_t *sum; - - sum = pgp_writer_get_arg(writer); - free(sum); -} - -/** -\ingroup Core_WritersNext -\param output -\param seckey -*/ -void -pgp_push_checksum_writer(pgp_output_t *output, pgp_seckey_t *seckey) -{ - /* XXX: push a SHA-1 checksum writer (and change s2k to 254). */ - skey_checksum_t *sum; - unsigned hashsize; - - if ((sum = calloc(1, sizeof(*sum))) == NULL) { - (void) fprintf(stderr, - "pgp_push_checksum_writer: bad alloc\n"); - } else { - /* configure the arg */ - /* Hardcoded SHA1 for just now */ - sum->hash_alg = PGP_HASH_SHA1; - hashsize = pgp_hash_size(sum->hash_alg); - if ((sum->hashed = seckey->checkhash) == NULL) { - sum->hashed = seckey->checkhash = calloc(1, hashsize); - } - /* init the hash */ - pgp_hash_any(&sum->hash, sum->hash_alg); - if (!sum->hash.init(&sum->hash)) { - (void) fprintf(stderr, - "pgp_push_checksum_writer: bad hash init\n"); - /* just continue and die */ - /* XXX - agc - no way to return failure */ - } - pgp_writer_push(output, skey_checksum_writer, - skey_checksum_finaliser, skey_checksum_destroyer, sum); - } -} - -/**************************************************************************/ - -typedef struct { - uint16_t sum; -} sum16_t; - -static unsigned -sum16_writer(const uint8_t *src, - const unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - sum16_t *arg; - unsigned ret = 1; - int n; - - arg = pgp_writer_get_arg(writer); - - for (n = 0; n < len; ++n) { - arg->sum = (arg->sum + src[n]) & 0xffff; - } - - /* write to next stacked writer */ - ret = stacked_write(writer, src, len, errors); - /* tidy up and return */ - return ret; -} - -void -pgp_push_sum16_writer(pgp_output_t *output) -{ - sum16_t *sum; - - if ((sum = calloc(1, sizeof(*sum))) == NULL) { - (void) fprintf(stderr, - "pgp_push_sum16_writer: bad alloc\n"); - } else { - pgp_writer_push(output, sum16_writer, - NULL, NULL, sum); - } -} - -uint16_t -pgp_pop_sum16_writer(pgp_output_t *output) -{ - uint16_t sum; - sum16_t *arg; - arg = pgp_writer_get_arg(&output->writer); - sum = arg->sum; - pgp_writer_pop(output); - free(arg); - return sum; -} - -/**************************************************************************/ - -#define MAX_PARTIAL_DATA_LENGTH 1073741824 - -typedef struct { - pgp_crypt_t *crypt; - pgp_memory_t *mem_data; - pgp_memory_t *litmem; - pgp_output_t *litoutput; - pgp_memory_t *se_ip_mem; - pgp_output_t *se_ip_out; - pgp_hash_t hash; -} str_enc_se_ip_t; - - -static unsigned -str_enc_se_ip_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer); - -static unsigned -str_enc_se_ip_finaliser(pgp_error_t **errors, - pgp_writer_t * writer); - -static void str_enc_se_ip_destroyer(pgp_writer_t *writer); - -/* */ - -/** -\ingroup Core_WritersNext -\param output -\param pubkey -*/ -void -pgp_push_stream_enc_se_ip(pgp_output_t *output, pgp_key_t *pubkey, const char *cipher) -{ - pgp_pk_sesskey_t *encrypted_pk_sesskey; - str_enc_se_ip_t *se_ip; - const unsigned bufsz = 1024; - pgp_crypt_t *encrypted; - uint8_t *iv; - - if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) { - (void) fprintf(stderr, - "pgp_push_stream_enc_se_ip: bad alloc\n"); - return; - } - encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher, NULL); - pgp_write_pk_sesskey(output, encrypted_pk_sesskey); - - /* Setup the se_ip */ - if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) { - free(se_ip); - (void) fprintf(stderr, - "pgp_push_stream_enc_se_ip: bad alloc\n"); - return; - } - pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg); - if ((iv = calloc(1, encrypted->blocksize)) == NULL) { - free(encrypted); - free(se_ip); - (void) fprintf(stderr, - "pgp_push_stream_enc_se_ip: bad alloc\n"); - return; - } - encrypted->set_iv(encrypted, iv); - encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]); - pgp_encrypt_init(encrypted); - - se_ip->crypt = encrypted; - - se_ip->mem_data = pgp_memory_new(); - pgp_memory_init(se_ip->mem_data, bufsz); - - se_ip->litmem = NULL; - se_ip->litoutput = NULL; - - pgp_setup_memory_write(&se_ip->se_ip_out, &se_ip->se_ip_mem, bufsz); - - /* And push writer on stack */ - pgp_writer_push(output, - str_enc_se_ip_writer, - str_enc_se_ip_finaliser, - str_enc_se_ip_destroyer, se_ip); - /* tidy up */ - free(encrypted_pk_sesskey); - free(iv); -} - - -/* calculate the partial data length */ -static unsigned -partial_data_len(unsigned len) -{ - unsigned mask; - int i; - - if (len == 0) { - (void) fprintf(stderr, "partial_data_len: 0 len\n"); - return 0; - } - if (len > MAX_PARTIAL_DATA_LENGTH) { - return MAX_PARTIAL_DATA_LENGTH; - } - mask = MAX_PARTIAL_DATA_LENGTH; - for (i = 0; i <= 30; i++) { - if (mask & len) { - break; - } - mask >>= 1; - } - return mask; -} - -static unsigned -write_partial_len(pgp_output_t *output, unsigned len) -{ - /* len must be a power of 2 from 0 to 30 */ - uint8_t c; - int i; - - for (i = 0; i <= 30; i++) { - if ((len >> i) & 1) { - break; - } - } - c = 224 + i; - return pgp_write(output, &c, 1); -} - -static unsigned -stream_write_litdata(pgp_output_t *output, - const uint8_t *data, - unsigned len) -{ - size_t pdlen; - - while (len > 0) { - pdlen = partial_data_len(len); - write_partial_len(output, (unsigned)pdlen); - pgp_write(output, data, (unsigned)pdlen); - data += pdlen; - len -= (unsigned)pdlen; - } - return 1; -} - -static unsigned -stream_write_litdata_first(pgp_output_t *output, - const uint8_t *data, - unsigned len, - const pgp_litdata_enum type) -{ - /* \todo add filename */ - /* \todo add date */ - /* \todo do we need to check text data for <cr><lf> line endings ? */ - - unsigned sz_towrite; - size_t sz_pd; - - sz_towrite = 1 + 1 + 4 + len; - sz_pd = (size_t)partial_data_len(sz_towrite); - if (sz_pd < 512) { - (void) fprintf(stderr, - "stream_write_litdata_first: bad sz_pd\n"); - return 0; - } - pgp_write_ptag(output, PGP_PTAG_CT_LITDATA); - write_partial_len(output, (unsigned)sz_pd); - pgp_write_scalar(output, (unsigned)type, 1); - pgp_write_scalar(output, 0, 1); - pgp_write_scalar(output, 0, 4); - pgp_write(output, data, (unsigned)(sz_pd - 6)); - - data += (sz_pd - 6); - sz_towrite -= (unsigned)sz_pd; - - return stream_write_litdata(output, data, (unsigned)sz_towrite); -} - -static unsigned -stream_write_litdata_last(pgp_output_t *output, - const uint8_t *data, - unsigned len) -{ - pgp_write_length(output, len); - return pgp_write(output, data, len); -} - -static unsigned -stream_write_se_ip(pgp_output_t *output, - const uint8_t *data, - unsigned len, - str_enc_se_ip_t *se_ip) -{ - size_t pdlen; - - while (len > 0) { - pdlen = partial_data_len(len); - write_partial_len(output, (unsigned)pdlen); - - pgp_push_enc_crypt(output, se_ip->crypt); - pgp_write(output, data, (unsigned)pdlen); - pgp_writer_pop(output); - - se_ip->hash.add(&se_ip->hash, data, (unsigned)pdlen); - - data += pdlen; - len -= (unsigned)pdlen; - } - return 1; -} - -static unsigned -stream_write_se_ip_first(pgp_output_t *output, - const uint8_t *data, - unsigned len, - str_enc_se_ip_t *se_ip) -{ - uint8_t *preamble; - size_t blocksize; - size_t preamblesize; - size_t sz_towrite; - size_t sz_pd; - - blocksize = se_ip->crypt->blocksize; - preamblesize = blocksize + 2; - sz_towrite = preamblesize + 1 + len; - if ((preamble = calloc(1, preamblesize)) == NULL) { - (void) fprintf(stderr, - "stream_write_se_ip_first: bad alloc\n"); - return 0; - } - sz_pd = (size_t)partial_data_len((unsigned)sz_towrite); - if (sz_pd < 512) { - free(preamble); - (void) fprintf(stderr, - "stream_write_se_ip_first: bad sz_pd\n"); - return 0; - } - pgp_write_ptag(output, PGP_PTAG_CT_SE_IP_DATA); - write_partial_len(output, (unsigned)sz_pd); - pgp_write_scalar(output, PGP_SE_IP_DATA_VERSION, 1); - pgp_push_enc_crypt(output, se_ip->crypt); - - pgp_random(preamble, blocksize); - preamble[blocksize] = preamble[blocksize - 2]; - preamble[blocksize + 1] = preamble[blocksize - 1]; - pgp_hash_any(&se_ip->hash, PGP_HASH_SHA1); - if (!se_ip->hash.init(&se_ip->hash)) { - free(preamble); - (void) fprintf(stderr, - "stream_write_se_ip_first: bad hash init\n"); - return 0; - } - pgp_write(output, preamble, (unsigned)preamblesize); - se_ip->hash.add(&se_ip->hash, preamble, (unsigned)preamblesize); - pgp_write(output, data, (unsigned)(sz_pd - preamblesize - 1)); - se_ip->hash.add(&se_ip->hash, data, (unsigned)(sz_pd - preamblesize - 1)); - data += (sz_pd - preamblesize - 1); - sz_towrite -= sz_pd; - pgp_writer_pop(output); - stream_write_se_ip(output, data, (unsigned)sz_towrite, se_ip); - free(preamble); - return 1; -} - -static unsigned -stream_write_se_ip_last(pgp_output_t *output, - const uint8_t *data, - unsigned len, - str_enc_se_ip_t *se_ip) -{ - pgp_output_t *mdcoutput; - pgp_memory_t *mdcmem; - const size_t mdcsize = 1 + 1 + PGP_SHA1_HASH_SIZE; - uint8_t c; - uint8_t hashed[PGP_SHA1_HASH_SIZE]; - size_t bufsize = len + mdcsize; - - se_ip->hash.add(&se_ip->hash, data, len); - - /* MDC packet tag */ - c = MDC_PKT_TAG; - se_ip->hash.add(&se_ip->hash, &c, 1); - - /* MDC packet len */ - c = PGP_SHA1_HASH_SIZE; - se_ip->hash.add(&se_ip->hash, &c, 1); - - /* finish */ - se_ip->hash.finish(&se_ip->hash, hashed); - - pgp_setup_memory_write(&mdcoutput, &mdcmem, mdcsize); - pgp_write_mdc(mdcoutput, hashed); - - /* write length of last se_ip chunk */ - pgp_write_length(output, (unsigned)bufsize); - - /* encode everting */ - pgp_push_enc_crypt(output, se_ip->crypt); - - pgp_write(output, data, len); - pgp_write(output, pgp_mem_data(mdcmem), (unsigned)pgp_mem_len(mdcmem)); - - pgp_writer_pop(output); - - pgp_teardown_memory_write(mdcoutput, mdcmem); - - return 1; -} - -static unsigned -str_enc_se_ip_writer(const uint8_t *src, - unsigned len, - pgp_error_t **errors, - pgp_writer_t *writer) -{ - str_enc_se_ip_t *se_ip; - unsigned ret; - size_t datalength; - - se_ip = pgp_writer_get_arg(writer); - if (se_ip->litoutput == NULL) { - /* first literal data chunk is not yet written */ - - pgp_memory_add(se_ip->mem_data, src, len); - datalength = pgp_mem_len(se_ip->mem_data); - - /* 4.2.2.4. Partial Body Lengths */ - /* The first partial length MUST be at least 512 octets long. */ - if (datalength < 512) { - return 1; /* will wait for more data or - * end of stream */ - } - pgp_setup_memory_write(&se_ip->litoutput, - &se_ip->litmem, datalength + 32); - stream_write_litdata_first(se_ip->litoutput, - pgp_mem_data(se_ip->mem_data), - (unsigned)datalength, - PGP_LDT_BINARY); - - stream_write_se_ip_first(se_ip->se_ip_out, - pgp_mem_data(se_ip->litmem), - (unsigned)pgp_mem_len(se_ip->litmem), se_ip); - } else { - stream_write_litdata(se_ip->litoutput, src, len); - stream_write_se_ip(se_ip->se_ip_out, - pgp_mem_data(se_ip->litmem), - (unsigned)pgp_mem_len(se_ip->litmem), se_ip); - } - - /* now write memory to next writer */ - ret = stacked_write(writer, pgp_mem_data(se_ip->se_ip_mem), - (unsigned)pgp_mem_len(se_ip->se_ip_mem), errors); - - pgp_memory_clear(se_ip->litmem); - pgp_memory_clear(se_ip->se_ip_mem); - - return ret; -} - -/* write last chunk of data */ -static unsigned -str_enc_se_ip_finaliser(pgp_error_t **errors, pgp_writer_t *writer) -{ - str_enc_se_ip_t *se_ip; - - se_ip = pgp_writer_get_arg(writer); - if (se_ip->litoutput == NULL) { - /* first literal data chunk was not written */ - /* so we know the total length of data, write a simple packet */ - - /* create literal data packet from buffered data */ - pgp_setup_memory_write(&se_ip->litoutput, &se_ip->litmem, - pgp_mem_len(se_ip->mem_data) + 32); - - pgp_write_litdata(se_ip->litoutput, - pgp_mem_data(se_ip->mem_data), - (const int)pgp_mem_len(se_ip->mem_data), - PGP_LDT_BINARY); - - /* create SE IP packet set from this literal data */ - pgp_write_se_ip_pktset(se_ip->se_ip_out, - pgp_mem_data(se_ip->litmem), - (unsigned)pgp_mem_len(se_ip->litmem), - se_ip->crypt); - - } else { - /* finish writing */ - stream_write_litdata_last(se_ip->litoutput, NULL, 0); - stream_write_se_ip_last(se_ip->se_ip_out, - pgp_mem_data(se_ip->litmem), - (unsigned)pgp_mem_len(se_ip->litmem), se_ip); - } - - /* now write memory to next writer */ - return stacked_write(writer, pgp_mem_data(se_ip->se_ip_mem), - (unsigned)pgp_mem_len(se_ip->se_ip_mem), errors); -} - -static void -str_enc_se_ip_destroyer(pgp_writer_t *writer) -{ - str_enc_se_ip_t *se_ip; - - se_ip = pgp_writer_get_arg(writer); - pgp_memory_free(se_ip->mem_data); - pgp_teardown_memory_write(se_ip->litoutput, se_ip->litmem); - pgp_teardown_memory_write(se_ip->se_ip_out, se_ip->se_ip_mem); - - se_ip->crypt->decrypt_finish(se_ip->crypt); - - free(se_ip->crypt); - free(se_ip); -}