Losslessly encode protos

This commit is contained in:
Michael Kirk 2019-07-13 09:06:47 -06:00
parent e0ed377f45
commit 5826648598
10 changed files with 504 additions and 540 deletions

View File

@ -48,10 +48,9 @@ public enum SMKCertificateError: Error {
// if (!Curve.verifySignature(serverCertificate.getKey(), certificate.getCertificate(), certificate.getSignature())) {
// throw new InvalidCertificateException("Signature failed");
// }
let certificateData = try senderCertificate.toProto().certificate
guard try Ed25519.verifySignature(senderCertificate.signatureData,
publicKey: serverCertificate.key.keyData,
data: certificateData) else {
data: senderCertificate.certificateData) else {
Logger.error("Sender certificate signature verification failed.")
let error = SMKCertificateError.invalidCertificate(description: "Sender certificate signature verification failed.")
Logger.error("\(error)")
@ -79,14 +78,10 @@ public enum SMKCertificateError: Error {
// if (!Curve.verifySignature(trustRoot, certificate.getCertificate(), certificate.getSignature())) {
// throw new InvalidCertificateException("Signature failed");
// }
let certificateBuilder = SMKProtoServerCertificateCertificate.builder(id: serverCertificate.keyId,
key: serverCertificate.key.serialized)
let certificateData = try certificateBuilder.build().serializedData()
// let certificateData = try serverCertificate.toProto().certificate
guard try Ed25519.verifySignature(serverCertificate.signatureData,
publicKey: trustRoot.keyData,
data: certificateData) else {
data: serverCertificate.certificateData) else {
let error = SMKCertificateError.invalidCertificate(description: "Server certificate signature verification failed.")
Logger.error("\(error)")
throw error

View File

@ -241,21 +241,21 @@ public class SMKDecryptResult: NSObject {
default:
throw SMKError.assertionError(description: "\(logTag) Unknown cipher message type.")
}
let messageContent = SMKUnidentifiedSenderMessageContent(messageType: messageType,
let messageContent = try SMKUnidentifiedSenderMessageContent(messageType: messageType,
senderCertificate: senderCertificate,
contentData: encryptedMessageData)
// byte[] messageBytes = encrypt(staticKeys.cipherKey, staticKeys.macKey, content.getSerialized());
let messageData = try encrypt(cipherKey: staticKeys.cipherKey,
macKey: staticKeys.macKey,
plaintextData: try messageContent.serialized())
plaintextData: messageContent.serializedData)
// return new UnidentifiedSenderMessage(ephemeral.getPublicKey(), staticKeyCiphertext,
// messageBytes).getSerialized();
let message = SMKUnidentifiedSenderMessage(ephemeralKey: try ephemeral.ecPublicKey(),
let message = try SMKUnidentifiedSenderMessage(ephemeralKey: try ephemeral.ecPublicKey(),
encryptedStatic: staticKeyCipherData,
encryptedMessage: messageData)
return try message.serialized()
return message.serializedData
}
// public Pair<SignalProtocolAddress, byte[]> decrypt(CertificateValidator validator, byte[] ciphertext, long
@ -282,7 +282,7 @@ public class SMKDecryptResult: NSObject {
}
// UnidentifiedSenderMessage wrapper = new UnidentifiedSenderMessage(ciphertext);
let wrapper = try SMKUnidentifiedSenderMessage.parse(dataAndPrefix: cipherTextData)
let wrapper = try SMKUnidentifiedSenderMessage(serializedData: cipherTextData)
// byte[] ephemeralSalt = ByteUtil.combine("UnidentifiedDelivery".getBytes(),
// ourIdentity.getPublicKey().getPublicKey().serialize(), wrapper.getEphemeral().serialize());
@ -326,7 +326,7 @@ public class SMKDecryptResult: NSObject {
cipherTextWithMac: wrapper.encryptedMessage)
// content = new UnidentifiedSenderMessageContent(messageBytes);
let messageContent = try SMKUnidentifiedSenderMessageContent.parse(data: messageBytes)
let messageContent = try SMKUnidentifiedSenderMessageContent(serializedData: messageBytes)
let senderRecipientId = messageContent.senderCertificate.senderRecipientId
let senderDeviceId = messageContent.senderCertificate.senderDeviceId

View File

@ -13,76 +13,41 @@ import Foundation
@objc public let senderDeviceId: UInt32
@objc public let senderRecipientId: String
@objc public let expirationTimestamp: UInt64
@objc public let serializedData: Data
@objc public let certificateData: Data
@objc public let signatureData: Data
@objc public init(signer: SMKServerCertificate,
key: ECPublicKey,
senderDeviceId: UInt32,
senderRecipientId: String,
expirationTimestamp: UInt64,
signatureData: Data) {
self.signer = signer
self.key = key
self.senderDeviceId = senderDeviceId
self.senderRecipientId = senderRecipientId
self.expirationTimestamp = expirationTimestamp
self.signatureData = signatureData
}
public init(serializedData: Data) throws {
// SignalProtos.SenderCertificate wrapper = SignalProtos.SenderCertificate.parseFrom(serialized);
//
// if (!wrapper.hasSignature() || !wrapper.hasCertificate()) {
// throw new InvalidCertificateException("Missing fields");
// }
let wrapperProto = try SMKProtoSenderCertificate.parseData(serializedData)
@objc public class func parse(data: Data) throws -> SMKSenderCertificate {
let proto = try SMKProtoSenderCertificate.parseData(data)
return try parse(proto: proto)
}
// SignalProtos.SenderCertificate.Certificate certificate = SignalProtos.SenderCertificate.Certificate.parseFrom(wrapper.getCertificate());
//
// if (!certificate.hasSigner() || !certificate.hasIdentityKey() || !certificate.hasSenderDevice() || !certificate.hasExpires() || !certificate.hasSender()) {
// throw new InvalidCertificateException("Missing fields");
// }
let certificateProto = try SMKProtoSenderCertificateCertificate.parseData(wrapperProto.certificate)
@objc public class func parse(proto: SMKProtoSenderCertificate) throws -> SMKSenderCertificate {
// this.signer = new ServerCertificate(certificate.getSigner().toByteArray());
// this.key = Curve.decodePoint(certificate.getIdentityKey().toByteArray(), 0);
// this.sender = certificate.getSender();
// this.senderDeviceId = certificate.getSenderDevice();
// this.expiration = certificate.getExpires();
self.signer = try SMKServerCertificate(serializedData: certificateProto.signer.serializedData())
self.key = try ECPublicKey(serializedKeyData: certificateProto.identityKey)
self.senderRecipientId = certificateProto.sender
self.senderDeviceId = certificateProto.senderDevice
self.expirationTimestamp = certificateProto.expires
let certificateData = proto.certificate
let signatureData = proto.signature
let certificateProto = try SMKProtoSenderCertificateCertificate.parseData(certificateData)
let keyData = certificateProto.identityKey
let key = try ECPublicKey(serializedKeyData: keyData)
let senderDeviceId = certificateProto.senderDevice
let senderRecipientId = certificateProto.sender
let expirationTimestamp = certificateProto.expires
let signerProto = certificateProto.signer
let signer = try SMKServerCertificate.parse(proto: signerProto)
return SMKSenderCertificate(signer: signer, key: key, senderDeviceId: senderDeviceId, senderRecipientId: senderRecipientId, expirationTimestamp: expirationTimestamp, signatureData: signatureData)
}
@objc public func toProto() throws -> SMKProtoSenderCertificate {
let certificateBuilder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: key.serialized,
signer: try signer.toProto())
let builder =
SMKProtoSenderCertificate.builder(certificate: try certificateBuilder.buildSerializedData(),
signature: signatureData)
return try builder.build()
}
@objc public func serialized() throws -> Data {
return try toProto().serializedData()
}
open override func isEqual(_ other: Any?) -> Bool {
if let other = other as? SMKSenderCertificate {
return (signer.isEqual(other.signer) &&
key.isEqual(other.key) &&
senderDeviceId == other.senderDeviceId &&
senderRecipientId == other.senderRecipientId &&
expirationTimestamp == other.expirationTimestamp &&
signatureData == other.signatureData)
} else {
return false
}
}
public override var hash: Int {
return signer.hashValue ^ key.hashValue ^ senderDeviceId.hashValue ^ senderRecipientId.hashValue ^ expirationTimestamp.hashValue ^ signatureData.hashValue
// this.serialized = serialized;
// this.certificate = wrapper.getCertificate().toByteArray();
// this.signature = wrapper.getSignature().toByteArray();
self.serializedData = serializedData
self.certificateData = wrapperProto.certificate
self.signatureData = wrapperProto.signature
}
}

View File

@ -10,55 +10,37 @@ import Foundation
@objc public let keyId: UInt32
@objc public let key: ECPublicKey
@objc public let serializedData: Data
@objc public let certificateData: Data
@objc public let signatureData: Data
public init(keyId: UInt32,
key: ECPublicKey,
signatureData: Data) {
self.keyId = keyId
self.key = key
self.signatureData = signatureData
}
// public ServerCertificate(byte[] serialized) throws InvalidCertificateException {
public init(serializedData: Data) throws {
// SignalProtos.ServerCertificate wrapper = SignalProtos.ServerCertificate.parseFrom(serialized);
// if (!wrapper.hasCertificate() || !wrapper.hasSignature()) {
// throw new InvalidCertificateException("Missing fields");
// }
let wrapperProto = try SMKProtoServerCertificate.parseData(serializedData)
@objc public class func parse(data: Data) throws -> SMKServerCertificate {
let proto = try SMKProtoServerCertificate.parseData(data)
return try parse(proto: proto)
}
// SignalProtos.ServerCertificate.Certificate certificate = // SignalProtos.ServerCertificate.Certificate.parseFrom(wrapper.getCertificate());
//
// if (!certificate.hasId() || !certificate.hasKey()) {
// throw new InvalidCertificateException("Missing fields");
// }
let certificateProto = try SMKProtoServerCertificateCertificate.parseData(wrapperProto.certificate)
@objc public class func parse(proto: SMKProtoServerCertificate) throws -> SMKServerCertificate {
let signatureData = proto.signature
let certificateData = proto.certificate
let certificateProto = try SMKProtoServerCertificateCertificate.parseData(certificateData)
let keyId = certificateProto.id
let keyData = certificateProto.key
let key = try ECPublicKey(serializedKeyData: keyData)
return SMKServerCertificate(keyId: keyId, key: key, signatureData: signatureData)
}
// this.keyId = certificate.getId();
self.keyId = certificateProto.id
@objc public func toProto() throws -> SMKProtoServerCertificate {
let certificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId, key: key.serialized)
// this.key = Curve.decodePoint(certificate.getKey().toByteArray(), 0);
self.key = try ECPublicKey(serializedKeyData: certificateProto.key)
let builder =
SMKProtoServerCertificate.builder(certificate: try certificateBuilder.buildSerializedData(),
signature: signatureData)
return try builder.build()
}
// this.serialized = serialized;
self.serializedData = serializedData
@objc public func serialized() throws -> Data {
return try toProto().serializedData()
}
open override func isEqual(_ other: Any?) -> Bool {
if let other = other as? SMKServerCertificate {
return (keyId == other.keyId &&
key.isEqual(other.key) &&
(signatureData == other.signatureData))
} else {
return false
}
}
public override var hash: Int {
return keyId.hashValue ^ key.hashValue ^ signatureData.hashValue
// this.certificate = wrapper.getCertificate().toByteArray();
// this.signature = wrapper.getSignature().toByteArray();
self.certificateData = wrapperProto.certificate
self.signatureData = wrapperProto.signature
}
}

View File

@ -13,41 +13,23 @@ import Foundation
public let ephemeralKey: ECPublicKey
public let encryptedStatic: Data
public let encryptedMessage: Data
public let serializedData: Data
public init(cipherTextVersion: UInt,
ephemeralKey: ECPublicKey,
encryptedStatic: Data,
encryptedMessage: Data) {
self.cipherTextVersion = cipherTextVersion
self.ephemeralKey = ephemeralKey
self.encryptedStatic = encryptedStatic
self.encryptedMessage = encryptedMessage
}
public init(ephemeralKey: ECPublicKey,
encryptedStatic: Data,
encryptedMessage: Data) {
self.cipherTextVersion = SMKUnidentifiedSenderMessage.kSMKMessageCipherTextVersion
self.ephemeralKey = ephemeralKey
self.encryptedStatic = encryptedStatic
self.encryptedMessage = encryptedMessage
}
@objc public class func parse(dataAndPrefix: Data) throws -> SMKUnidentifiedSenderMessage {
public init(serializedData: Data) throws {
// public UnidentifiedSenderMessage(byte[] serialized)
// throws InvalidMetadataMessageException, InvalidMetadataVersionException
let parser = OWSDataParser(data: dataAndPrefix)
let parser = OWSDataParser(data: serializedData)
// this.version = ByteUtil.highBitsToInt(serialized[0]);
let versionByte = try parser.nextByte(name: "version byte")
let cipherTextVersion = UInt(SerializationUtilities.highBitsToInt(fromByte: versionByte))
self.cipherTextVersion = UInt(SerializationUtilities.highBitsToInt(fromByte: versionByte))
// if (version > CIPHERTEXT_VERSION) {
// throw new InvalidMetadataVersionException("Unknown version: " + this.version);
// }
guard cipherTextVersion <= SMKUnidentifiedSenderMessage.kSMKMessageCipherTextVersion else {
throw SMKError.assertionError(description: "\(logTag) unknown cipher text version: \(cipherTextVersion)")
throw SMKError.assertionError(description: "\(type(of: self)) unknown cipherTextVersion: \(cipherTextVersion)")
}
// SignalProtos.UnidentifiedSenderMessage unidentifiedSenderMessage =
@ -65,30 +47,45 @@ import Foundation
// this.ephemeral = Curve.decodePoint(unidentifiedSenderMessage.getEphemeralPublic().toByteArray(), 0);
let ephemeralKeyData = proto.ephemeralPublic
let ephemeralKey = try ECPublicKey(serializedKeyData: ephemeralKeyData)
self.ephemeralKey = try ECPublicKey(serializedKeyData: ephemeralKeyData)
// this.encryptedStatic = unidentifiedSenderMessage.getEncryptedStatic().toByteArray();
let encryptedStatic = proto.encryptedStatic
self.encryptedStatic = proto.encryptedStatic
// this.encryptedMessage = unidentifiedSenderMessage.getEncryptedMessage().toByteArray();
let encryptedMessage = proto.encryptedMessage
self.encryptedMessage = proto.encryptedMessage
return SMKUnidentifiedSenderMessage(cipherTextVersion: cipherTextVersion, ephemeralKey: ephemeralKey, encryptedStatic: encryptedStatic, encryptedMessage: encryptedMessage)
// this.serialized = serialized;
self.serializedData = serializedData
}
@objc public func toProto() throws -> SMKProtoUnidentifiedSenderMessage {
let builder = SMKProtoUnidentifiedSenderMessage.builder(ephemeralPublic: ephemeralKey.serialized,
encryptedStatic: encryptedStatic,
encryptedMessage: encryptedMessage)
return try builder.build()
}
// public UnidentifiedSenderMessage(ECPublicKey ephemeral, byte[] encryptedStatic, byte[] encryptedMessage) {
public init(ephemeralKey: ECPublicKey, encryptedStatic: Data, encryptedMessage: Data) throws {
// this.version = CIPHERTEXT_VERSION;
// this.ephemeral = ephemeral;
// this.encryptedStatic = encryptedStatic;
// this.encryptedMessage = encryptedMessage;
self.cipherTextVersion = SMKUnidentifiedSenderMessage.kSMKMessageCipherTextVersion
self.ephemeralKey = ephemeralKey
self.encryptedStatic = encryptedStatic
self.encryptedMessage = encryptedMessage
@objc public func serialized() throws -> Data {
// byte[] versionBytes = {ByteUtil.intsToByteHighAndLow(CIPHERTEXT_VERSION, CIPHERTEXT_VERSION)};
let versionByte: UInt8 = UInt8((self.cipherTextVersion << 4 | self.cipherTextVersion) & 0xFF)
let versionBytes = [versionByte]
let versionData = Data(versionBytes)
let messageData = try toProto().serializedData()
return NSData.join([versionData, messageData])
// byte[] messageBytes = SignalProtos.UnidentifiedSenderMessage.newBuilder()
// .setEncryptedMessage(ByteString.copyFrom(encryptedMessage))
// .setEncryptedStatic(ByteString.copyFrom(encryptedStatic))
// .setEphemeralPublic(ByteString.copyFrom(ephemeral.serialize()))
// .build()
// .toByteArray();
let messageData = try SMKProtoUnidentifiedSenderMessage.builder(ephemeralPublic: ephemeralKey.serialized,
encryptedStatic: encryptedStatic,
encryptedMessage: encryptedMessage).buildSerializedData()
// this.serialized = ByteUtil.combine(versionBytes, messageBytes);
self.serializedData = NSData.join([versionData, messageData])
}
}

View File

@ -16,53 +16,80 @@ import Foundation
@objc public let messageType: SMKMessageType
@objc public let senderCertificate: SMKSenderCertificate
@objc public let contentData: Data
@objc public let serializedData: Data
@objc public init(messageType: SMKMessageType,
senderCertificate: SMKSenderCertificate,
contentData: Data) {
// public UnidentifiedSenderMessageContent(byte[] serialized) throws InvalidMetadataMessageException, InvalidCertificateException {
public init(serializedData: Data) throws {
// SignalProtos.UnidentifiedSenderMessage.Message message = SignalProtos.UnidentifiedSenderMessage.Message.parseFrom(serialized);
//
// if (!message.hasType() || !message.hasSenderCertificate() || !message.hasContent()) {
// throw new InvalidMetadataMessageException("Missing fields");
// }
let proto = try SMKProtoUnidentifiedSenderMessageMessage.parseData(serializedData)
// switch (message.getType()) {
// case MESSAGE: this.type = CiphertextMessage.WHISPER_TYPE; break;
// case PREKEY_MESSAGE: this.type = CiphertextMessage.PREKEY_TYPE; break;
// default: throw new InvalidMetadataMessageException("Unknown type: " + message.getType().getNumber());
// }
switch (proto.type) {
case .prekeyMessage?:
self.messageType = .prekey
case .message?:
self.messageType = .whisper
default:
throw SMKProtoError.invalidProtobuf(description: "\(type(of: self)) missing required field: proto.type")
}
// this.senderCertificate = new SenderCertificate(message.getSenderCertificate().toByteArray());
// this.content = message.getContent().toByteArray();
// this.serialized = serialized;
self.senderCertificate = try SMKSenderCertificate(serializedData: proto.senderCertificate.serializedData())
self.contentData = proto.content
self.serializedData = serializedData
}
// public UnidentifiedSenderMessageContent(int type, SenderCertificate senderCertificate, byte[] content) {
public init(messageType: SMKMessageType, senderCertificate: SMKSenderCertificate, contentData: Data) throws {
// try {
// this.serialized = SignalProtos.UnidentifiedSenderMessage.Message.newBuilder()
// .setType(SignalProtos.UnidentifiedSenderMessage.Message.Type.valueOf(getProtoType(type)))
// .setSenderCertificate(SignalProtos.SenderCertificate.parseFrom(senderCertificate.getSerialized()))
// .setContent(ByteString.copyFrom(content))
// .build()
// .toByteArray();
let senderCertificateProto = try SMKProtoSenderCertificate.parseData(senderCertificate.serializedData)
let messageProtoBuilder = SMKProtoUnidentifiedSenderMessageMessage.builder(senderCertificate: senderCertificateProto,
content: contentData)
messageProtoBuilder.setType(messageType.protoType)
self.serializedData = try messageProtoBuilder.buildSerializedData()
// this.type = type;
// this.senderCertificate = senderCertificate;
// this.content = content;
self.messageType = messageType
self.senderCertificate = senderCertificate
self.contentData = contentData
}
@objc public class func parse(data: Data) throws -> SMKUnidentifiedSenderMessageContent {
let proto = try SMKProtoUnidentifiedSenderMessageMessage.parseData(data)
// TODO: Should we have a default case in our switches? Probably.
var messageType: SMKMessageType
switch (proto.type) {
case .prekeyMessage?:
messageType = .prekey
case .message?:
messageType = .whisper
case .none:
throw SMKProtoError.invalidProtobuf(description: "\(logTag) missing required field: proto.type")
}
let contentData = proto.content
let senderCertificateProto = proto.senderCertificate
let senderCertificate = try SMKSenderCertificate.parse(proto: senderCertificateProto)
return SMKUnidentifiedSenderMessageContent(messageType: messageType, senderCertificate: senderCertificate, contentData: contentData)
}
@objc public func toProto() throws -> SMKProtoUnidentifiedSenderMessageMessage {
let builderType: SMKProtoUnidentifiedSenderMessageMessage.SMKProtoUnidentifiedSenderMessageMessageType
switch messageType {
case .whisper:
builderType = .message
case .prekey:
builderType = .prekeyMessage
}
let builder = SMKProtoUnidentifiedSenderMessageMessage.builder(senderCertificate: try senderCertificate.toProto(),
content: contentData)
builder.setType(builderType)
return try builder.build()
}
@objc public func serialized() throws -> Data {
return try toProto().serializedData()
// } catch (InvalidProtocolBufferException e) {
// throw new AssertionError(e);
// }
}
}
fileprivate extension SMKMessageType {
// private int getProtoType(int type) {
var protoType: SMKProtoUnidentifiedSenderMessageMessage.SMKProtoUnidentifiedSenderMessageMessageType {
// switch (type) {
// case CiphertextMessage.WHISPER_TYPE: return SignalProtos.UnidentifiedSenderMessage.Message.Type.MESSAGE_VALUE;
// case CiphertextMessage.PREKEY_TYPE: return SignalProtos.UnidentifiedSenderMessage.Message.Type.PREKEY_MESSAGE_VALUE;
// default: throw new AssertionError(type);
// }
switch self {
case .whisper:
return .message
case .prekey:
return .prekeyMessage
}
}
}

View File

@ -41,11 +41,10 @@ class SMKTest: XCTestCase {
let encryptedStatic = Randomness.generateRandomBytes(100)!
let encryptedMessage = Randomness.generateRandomBytes(200)!
let message = SMKUnidentifiedSenderMessage(ephemeralKey: ephemeralKey,
let message = try! SMKUnidentifiedSenderMessage(ephemeralKey: ephemeralKey,
encryptedStatic: encryptedStatic,
encryptedMessage: encryptedMessage)
let messageData = try! message.serialized()
let parsedMessage = try! SMKUnidentifiedSenderMessage.parse(dataAndPrefix: messageData)
let parsedMessage = try! SMKUnidentifiedSenderMessage(serializedData: message.serializedData)
XCTAssertEqual(message.cipherTextVersion, parsedMessage.cipherTextVersion)
XCTAssertEqual(message.ephemeralKey.keyData, parsedMessage.ephemeralKey.keyData)
XCTAssertEqual(message.encryptedStatic, parsedMessage.encryptedStatic)
@ -53,68 +52,49 @@ class SMKTest: XCTestCase {
}
func testUDServerCertificate() {
let keyId: UInt32 = 123
let key = try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!)
let signatureData = Randomness.generateRandomBytes(100)!
let serializedData = try! buildServerCertificateProto().serializedData()
let serverCertificate = SMKServerCertificate(keyId: keyId,
key: key,
signatureData: signatureData)
let serializedData = try! serverCertificate.serialized()
let parsed = try! SMKServerCertificate.parse(data: serializedData)
let serverCertificate = try! SMKServerCertificate(serializedData: serializedData)
let roundTripped = try! SMKServerCertificate(serializedData: serverCertificate.serializedData)
XCTAssertEqual(serverCertificate.keyId, parsed.keyId)
XCTAssertEqual(serverCertificate.key, parsed.key)
XCTAssertEqual(serverCertificate.signatureData, parsed.signatureData)
XCTAssertEqual(serverCertificate.keyId, roundTripped.keyId)
XCTAssertEqual(serverCertificate.key, roundTripped.key)
XCTAssertEqual(serverCertificate.signatureData, roundTripped.signatureData)
}
func testUDSenderCertificate() {
let serverCertificate = SMKServerCertificate(keyId: 123,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!),
signatureData: Randomness.generateRandomBytes(100)!)
let serializedData = try! buildSenderCertificateProto().serializedData()
let key = try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!)
let senderDeviceId: UInt32 = 456
let senderRecipientId = "+13213214321"
let expirationTimestamp: UInt64 = 789
let signatureData = Randomness.generateRandomBytes(100)!
let senderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: key,
senderDeviceId: senderDeviceId,
senderRecipientId: senderRecipientId,
expirationTimestamp: expirationTimestamp,
signatureData: signatureData)
let serializedData = try! senderCertificate.serialized()
let parsed = try! SMKSenderCertificate.parse(data: serializedData)
let senderCertificate = try! SMKSenderCertificate(serializedData: serializedData)
let roundTripped = try! SMKSenderCertificate(serializedData: senderCertificate.serializedData)
XCTAssertEqual(senderCertificate.signer, parsed.signer)
XCTAssertEqual(senderCertificate.key, parsed.key)
XCTAssertEqual(senderCertificate.senderDeviceId, parsed.senderDeviceId)
XCTAssertEqual(senderCertificate.senderRecipientId, parsed.senderRecipientId)
XCTAssertEqual(senderCertificate.expirationTimestamp, parsed.expirationTimestamp)
XCTAssertEqual(senderCertificate.signatureData, parsed.signatureData)
XCTAssertEqual(senderCertificate.signer.serializedData, roundTripped.signer.serializedData)
XCTAssertEqual(senderCertificate.key, roundTripped.key)
XCTAssertEqual(senderCertificate.senderDeviceId, roundTripped.senderDeviceId)
XCTAssertEqual(senderCertificate.senderRecipientId, roundTripped.senderRecipientId)
XCTAssertEqual(senderCertificate.expirationTimestamp, roundTripped.expirationTimestamp)
XCTAssertEqual(senderCertificate.signatureData, roundTripped.signatureData)
}
func testUDMessageContent() {
let serverCertificate = SMKServerCertificate(keyId: 123,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!),
signatureData: Randomness.generateRandomBytes(100)!)
let senderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!),
senderDeviceId: 456,
senderRecipientId: "+13213214321",
expirationTimestamp: 789,
signatureData: Randomness.generateRandomBytes(100)!)
let contentData = Randomness.generateRandomBytes(200)!
let senderCertificateProto = buildSenderCertificateProto()
let senderCertificate = try! SMKSenderCertificate(serializedData: try! senderCertificateProto.serializedData())
let message = SMKUnidentifiedSenderMessageContent(messageType: .whisper,
senderCertificate: senderCertificate,
contentData: contentData)
let messageData = try! message.serialized()
let parsed = try! SMKUnidentifiedSenderMessageContent.parse(data: messageData)
let contentData = Randomness.generateRandomBytes(200)!
let serializedData: Data = {
let builder = SMKProtoUnidentifiedSenderMessageMessage.builder(senderCertificate: senderCertificateProto,
content: contentData)
builder.setType(.message)
return try! builder.buildSerializedData()
}()
let parsed = try! SMKUnidentifiedSenderMessageContent(serializedData: serializedData)
let message = try! SMKUnidentifiedSenderMessageContent(messageType: .whisper,
senderCertificate: senderCertificate,
contentData: contentData)
XCTAssertEqual(message.messageType, parsed.messageType)
XCTAssertEqual(message.senderCertificate, parsed.senderCertificate)
XCTAssertEqual(message.senderCertificate.serializedData, parsed.senderCertificate.serializedData)
XCTAssertEqual(message.contentData, parsed.contentData)
}
@ -144,32 +124,73 @@ class SMKTest: XCTestCase {
let plaintext = Randomness.generateRandomBytes(200)!
let paddedPlaintext = (plaintext as NSData).paddedMessageBody()!
let serverCertificate = SMKServerCertificate(keyId: 123,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(Int32(ECCKeyLength))!),
signatureData: Randomness.generateRandomBytes(100)!)
let senderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! aliceMockClient.identityKeyPair.ecPublicKey(),
senderDeviceId: UInt32(aliceMockClient.deviceId),
senderRecipientId: aliceMockClient.recipientId,
expirationTimestamp: 789,
signatureData: Randomness.generateRandomBytes(100)!)
let senderCertificate = try! SMKSenderCertificate(serializedData: try! buildSenderCertificateProto(senderClient: aliceMockClient).serializedData())
let encryptedMessage = try! aliceToBobCipher.throwswrapped_encryptMessage(recipientId: bobMockClient.recipientId,
deviceId: bobMockClient.deviceId,
paddedPlaintext: paddedPlaintext, senderCertificate: senderCertificate, protocolContext: nil)
deviceId: bobMockClient.deviceId,
paddedPlaintext: paddedPlaintext,
senderCertificate: senderCertificate,
protocolContext: nil)
let messageTimestamp = NSDate.ows_millisecondTimeStamp()
let bobToAliceCipher = try! bobMockClient.createSecretSessionCipher()
let decryptedMessage = try! bobToAliceCipher.throwswrapped_decryptMessage(certificateValidator: certificateValidator,
cipherTextData: encryptedMessage,
timestamp: messageTimestamp,
localRecipientId: bobMockClient.recipientId,
localDeviceId: bobMockClient.deviceId,
protocolContext: nil)
cipherTextData: encryptedMessage,
timestamp: messageTimestamp,
localRecipientId: bobMockClient.recipientId,
localDeviceId: bobMockClient.deviceId,
protocolContext: nil)
let payload = (decryptedMessage.paddedPayload as NSData).removePadding()
XCTAssertEqual(aliceMockClient.recipientId, decryptedMessage.senderRecipientId)
XCTAssertEqual(aliceMockClient.deviceId, Int32(decryptedMessage.senderDeviceId))
XCTAssertEqual(plaintext, payload)
}
// MARK: - Util
func buildServerCertificateProto() -> SMKProtoServerCertificate {
let serverKey = try! Curve25519.generateKeyPair().ecPublicKey().serialized
let certificateData = try! SMKProtoServerCertificateCertificate.builder(id: 123,
key: serverKey ).buildSerializedData()
let signatureData = Randomness.generateRandomBytes(ECCSignatureLength)!
let wrapperProto = SMKProtoServerCertificate.builder(certificate: certificateData,
signature: signatureData)
return try! wrapperProto.build()
}
func buildSenderCertificateProto(senderClient: MockClient? = nil) -> SMKProtoSenderCertificate {
let sender: String
let senderDevice: UInt32
let expires = NSDate.ows_millisecondTimeStamp() + kWeekInMs
let identityKey: ECPublicKey
let signer = buildServerCertificateProto()
if let senderClient = senderClient {
sender = senderClient.recipientId
senderDevice = UInt32(senderClient.deviceId)
identityKey = try! senderClient.identityKeyPair.ecPublicKey()
} else {
sender = "+1235551234"
senderDevice = 123
identityKey = try! Curve25519.generateKeyPair().ecPublicKey()
}
let certificateData = try! SMKProtoSenderCertificateCertificate.builder(sender: sender,
senderDevice: senderDevice,
expires: expires,
identityKey: identityKey.serialized,
signer: signer)
.buildSerializedData()
let signatureData = Randomness.generateRandomBytes(ECCSignatureLength)!
let wrapperProto = try! SMKProtoSenderCertificate.builder(certificate: certificateData,
signature: signatureData).build()
return wrapperProto
}
}

View File

@ -272,62 +272,61 @@ class SMKSecretSessionCipherTest: XCTestCase {
// ECKeyPair serverKey = Curve.generateKeyPair();
let serverKey = Curve25519.generateKeyPair()
// byte[] serverCertificateBytes = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(serverKey.getPublicKey().serialize()))
// .build()
// .toByteArray();
let keyId: UInt32 = 1
let unsignedServerCertificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId,
key: try! serverKey.ecPublicKey().serialized)
let unsignedServerCertificateData = try! unsignedServerCertificateBuilder.build().serializedData()
// byte[] serverCertificateBytes = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(serverKey.getPublicKey().serialize()))
// .build()
// .toByteArray();
let serverCertificateBuilder = SMKProtoServerCertificateCertificate.builder(id: 1,
key: try! serverKey.ecPublicKey().serialized)
let serverCertificateData = try! serverCertificateBuilder.build().serializedData()
// byte[] serverCertificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), serverCertificateBytes);
let serverCertificateSignature = try! Ed25519.sign(unsignedServerCertificateData, with: trustRoot)
// byte[] serverCertificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), serverCertificateBytes);
let serverCertificateSignature = try! Ed25519.sign(serverCertificateData, with: trustRoot)
// ServerCertificate serverCertificate = new ServerCertificate(SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(serverCertificateBytes))
// .setSignature(ByteString.copyFrom(serverCertificateSignature))
// .build()
// .toByteArray());
let signedServerCertificate = SMKServerCertificate(keyId: keyId,
key: try! serverKey.ecPublicKey(),
signatureData: serverCertificateSignature)
XCTAssertEqual(try! signedServerCertificate.toProto().certificate, unsignedServerCertificateData)
_ = try! signedServerCertificate.serialized()
// ServerCertificate serverCertificate = new ServerCertificate(SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(serverCertificateBytes))
// .setSignature(ByteString.copyFrom(serverCertificateSignature))
// .build()
// .toByteArray());
let serverCertificate: SMKServerCertificate = {
let builder = SMKProtoServerCertificate.builder(certificate: serverCertificateData,
signature: serverCertificateSignature)
// byte[] senderCertificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender(sender)
// .setSenderDevice(deviceId)
// .setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
// .setExpires(expires)
// .setSigner(SignalProtos.ServerCertificate.parseFrom(serverCertificate.getSerialized()))
// .build()
// .toByteArray();
let unsignedSenderCertificateBuilder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: identityKey.serialized,
signer: try! signedServerCertificate.toProto())
let unsignedSenderCertificateData = try! unsignedSenderCertificateBuilder.build().serializedData()
return try! SMKServerCertificate(serializedData: try! builder.buildSerializedData())
}()
// byte[] senderCertificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), senderCertificateBytes);
let senderCertificateSignature = try! Ed25519.sign(unsignedSenderCertificateData, with: serverKey)
// byte[] senderCertificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender(sender)
// .setSenderDevice(deviceId)
// .setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
// .setExpires(expires)
// .setSigner(SignalProtos.ServerCertificate.parseFrom(serverCertificate.getSerialized()))
// .build()
// .toByteArray();
let senderCertificateData: Data = {
let signer = try! SMKProtoServerCertificate.parseData(serverCertificate.serializedData)
let builder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: identityKey.serialized,
signer: signer)
return try! builder.buildSerializedData()
}()
// return new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(senderCertificateBytes))
// .setSignature(ByteString.copyFrom(senderCertificateSignature))
// .build()
// .toByteArray());
// byte[] senderCertificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), senderCertificateBytes);
let senderCertificateSignature = try! Ed25519.sign(senderCertificateData, with: serverKey)
let signedSenderCertificate = SMKSenderCertificate(signer: signedServerCertificate,
key: identityKey,
senderDeviceId: senderDeviceId,
senderRecipientId: senderRecipientId,
expirationTimestamp: expirationTimestamp,
signatureData: senderCertificateSignature)
XCTAssertEqual(try! signedSenderCertificate.signer.toProto().certificate, unsignedServerCertificateData)
return signedSenderCertificate
// return new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(senderCertificateBytes))
// .setSignature(ByteString.copyFrom(senderCertificateSignature))
// .build()
// .toByteArray());
return {
let builder = SMKProtoSenderCertificate.builder(certificate: senderCertificateData,
signature: senderCertificateSignature)
return try! SMKSenderCertificate(serializedData: try! builder.buildSerializedData())
}()
}
// private void initializeSessions(TestInMemorySignalProtocolStore aliceStore, TestInMemorySignalProtocolStore bobStore)

View File

@ -30,46 +30,37 @@ class SMKSenderCertificateTest: XCTestCase {
let serverKey = Curve25519.generateKeyPair()
let key = Curve25519.generateKeyPair()
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
let signer = try! getServerCertificate(serverKey: serverKey)
let certificateData = try! SMKProtoSenderCertificateCertificate.builder(sender: "+14152222222",
senderDevice: 1,
expires: 31337,
identityKey: key.ecPublicKey().serialized,
signer: signer).buildSerializedData()
let senderRecipientId = "+14152222222"
let senderDeviceId: UInt32 = 1
let expirationTimestamp: UInt64 = 31337
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: serverKey)
let serverCertificate = getServerCertificate(serverKey: serverKey, trustRoot: trustRoot)
let unsignedCertificateBuilder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: try! key.ecPublicKey().serialized,
signer: try! serverCertificate.toProto())
unsignedCertificateBuilder.setSigner(try! serverCertificate.toProto())
let unsignedSenderCertificateData = try! unsignedCertificateBuilder.build().serializedData()
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build()
// .toByteArray());
let senderCertificateData = try! SMKProtoSenderCertificate.builder(certificate: certificateData,
signature: certificateSignature)
.buildSerializedData()
let senderCertificate = try! SMKSenderCertificate(serializedData: senderCertificateData)
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let senderCertificateSignature = try! Ed25519.sign(unsignedSenderCertificateData, with: serverKey)
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build()
// .toByteArray());
let signedSenderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! key.ecPublicKey(),
senderDeviceId: senderDeviceId,
senderRecipientId: senderRecipientId,
expirationTimestamp: expirationTimestamp,
signatureData: senderCertificateSignature)
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31336);
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31336);
let certificateValidator = try! SMKCertificateDefaultValidator(trustRoot: trustRoot.ecPublicKey())
try! certificateValidator.throwswrapped_validate(senderCertificate: signedSenderCertificate, validationTime: 31336)
try! certificateValidator.throwswrapped_validate(senderCertificate: senderCertificate, validationTime: 31336)
}
// public void testExpiredSignature() throws InvalidCertificateException, InvalidKeyException {
@ -77,51 +68,44 @@ class SMKSenderCertificateTest: XCTestCase {
// ECKeyPair serverKey = Curve.generateKeyPair();
// ECKeyPair key = Curve.generateKeyPair();
let serverKey = Curve25519.generateKeyPair()
let key = Curve25519.generateKeyPair()
let key = Curve25519.generateKeyPair()
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
let senderRecipientId = "+14152222222"
let senderDeviceId: UInt32 = 1
let expirationTimestamp: UInt64 = 31337
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
let signer = try! getServerCertificate(serverKey: serverKey)
let certificateData = try! SMKProtoSenderCertificateCertificate.builder(sender: "+14152222222",
senderDevice: 1,
expires: 31337,
identityKey: key.ecPublicKey().serialized,
signer: signer).buildSerializedData()
let serverCertificate = getServerCertificate(serverKey: serverKey, trustRoot: trustRoot)
let unsignedCertificateBuilder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: try! key.ecPublicKey().serialized,
signer: try! serverCertificate.toProto())
let unsignedSenderCertificateData = try! unsignedCertificateBuilder.build().serializedData()
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: serverKey)
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let senderCertificateSignature = try! Ed25519.sign(unsignedSenderCertificateData, with: serverKey)
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build()
// .toByteArray());
let senderCertificateData = try! SMKProtoSenderCertificate.builder(certificate: certificateData,
signature: certificateSignature)
.buildSerializedData()
let senderCertificate = try! SMKSenderCertificate(serializedData: senderCertificateData)
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build()
// .toByteArray());
let signedSenderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! key.ecPublicKey(),
senderDeviceId: senderDeviceId,
senderRecipientId: senderRecipientId,
expirationTimestamp: expirationTimestamp,
signatureData: senderCertificateSignature)
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31338);
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31338);
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
let certificateValidator = try! SMKCertificateDefaultValidator(trustRoot: trustRoot.ecPublicKey())
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(senderCertificate: signedSenderCertificate, validationTime: 31338))
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(senderCertificate: senderCertificate, validationTime: 31338))
}
// public void testBadSignature() throws InvalidCertificateException, InvalidKeyException {
@ -129,92 +113,82 @@ class SMKSenderCertificateTest: XCTestCase {
// ECKeyPair serverKey = Curve.generateKeyPair();
// ECKeyPair key = Curve.generateKeyPair();
let serverKey = Curve25519.generateKeyPair()
let key = Curve25519.generateKeyPair()
let key = Curve25519.generateKeyPair()
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
let senderRecipientId = "+14152222222"
let senderDeviceId: UInt32 = 1
let expirationTimestamp: UInt64 = 31337
// byte[] certificateBytes = SignalProtos.SenderCertificate.Certificate.newBuilder()
// .setSender("+14152222222")
// .setSenderDevice(1)
// .setExpires(31337)
// .setIdentityKey(ByteString.copyFrom(key.getPublicKey().serialize()))
// .setSigner(getServerCertificate(serverKey))
// .build()
// .toByteArray();
let signer = try! getServerCertificate(serverKey: serverKey)
let certificateData = try! SMKProtoSenderCertificateCertificate.builder(sender: "+14152222222",
senderDevice: 1,
expires: 31337,
identityKey: key.ecPublicKey().serialized,
signer: signer).buildSerializedData()
let serverCertificate = getServerCertificate(serverKey: serverKey, trustRoot: trustRoot)
let unsignedCertificateBuilder = SMKProtoSenderCertificateCertificate.builder(sender: senderRecipientId,
senderDevice: senderDeviceId,
expires: expirationTimestamp,
identityKey: try! key.ecPublicKey().serialized,
signer: try! serverCertificate.toProto())
let unsignedSenderCertificateData = try! unsignedCertificateBuilder.build().serializedData()
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: serverKey)
// byte[] certificateSignature = Curve.calculateSignature(serverKey.getPrivateKey(), certificateBytes);
let senderCertificateSignature = try! Ed25519.sign(unsignedSenderCertificateData, with: serverKey)
// for (int i=0;i<certificateSignature.length;i++) {
for i in 0..<senderCertificateSignature.count {
// for (int b=0;b<8;b++) {
// for (int i=0;i<certificateSignature.length;i++) {
// for (int b=0;b<8;b++) {
for i in 0..<certificateSignature.count {
for b in 0..<8 {
// byte[] badSignature = new byte[certificateSignature.length];
// System.arraycopy(certificateSignature, 0, badSignature, 0, certificateSignature.length);
var badSignature = senderCertificateSignature
var badSignature = certificateSignature
// badSignature[i] = (byte)(badSignature[i] ^ 1 << b);
badSignature.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
bytes[i] = (UInt8)(bytes[i] ^ 1 << b)
}
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(badSignature))
// .build()
// .toByteArray());
let signedSenderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! key.ecPublicKey(),
senderDeviceId: senderDeviceId,
senderRecipientId: senderRecipientId,
expirationTimestamp: expirationTimestamp,
signatureData: badSignature)
// SenderCertificate senderCertificate = new SenderCertificate(SignalProtos.SenderCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(badSignature))
// .build()
// .toByteArray());
let serializedData = try! SMKProtoSenderCertificate.builder(certificate: certificateData,
signature: badSignature).buildSerializedData()
let senderCertificate = try! SMKSenderCertificate(serializedData: serializedData)
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31336);
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(senderCertificate, 31336);
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
let certificateValidator = try! SMKCertificateDefaultValidator(trustRoot: trustRoot.ecPublicKey())
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(senderCertificate: signedSenderCertificate, validationTime: 31336))
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(senderCertificate: senderCertificate,
validationTime: 31336))
}
}
}
// MARK: - Utils
// private SignalProtos.ServerCertificate getServerCertificate(ECKeyPair serverKey) throws InvalidKeyException, InvalidCertificateException {
private func getServerCertificate(serverKey: ECKeyPair, trustRoot: ECKeyPair) -> SMKServerCertificate {
// byte[] certificateBytes = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(serverKey.getPublicKey().serialize()))
// .build()
// .toByteArray();
let keyId: UInt32 = 1
let unsignedServerCertificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId,
key: try! serverKey.ecPublicKey().serialized)
let unsignedServerCertificateData = try! unsignedServerCertificateBuilder.build().serializedData()
// private SignalProtos.ServerCertificate getServerCertificate(ECKeyPair serverKey) throws InvalidKeyException, InvalidCertificateException {
private func getServerCertificate(serverKey: ECKeyPair) throws -> SMKProtoServerCertificate {
// byte[] certificateBytes = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(serverKey.getPublicKey().serialize()))
// .build()
// .toByteArray();
let certificateData = try! SMKProtoServerCertificateCertificate.builder(id: 1,
key: serverKey.ecPublicKey().serialized)
.buildSerializedData()
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let serverCertificateSignature = try! Ed25519.sign(unsignedServerCertificateData, with: trustRoot)
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: trustRoot)
// return SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build();
let signedServerCertificate = SMKServerCertificate(keyId: keyId,
key: try! serverKey.ecPublicKey(),
signatureData: serverCertificateSignature)
return signedServerCertificate
// return SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build();
return try! SMKProtoServerCertificate.builder(certificate: certificateData,
signature: certificateSignature).build()
}
}

View File

@ -60,33 +60,31 @@ class SMKServerCertificateTest: XCTestCase {
let trustRoot = Curve25519.generateKeyPair()
let keyPair = Curve25519.generateKeyPair()
// SignalProtos.ServerCertificate.Certificate certificate = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(keyPair.getPublicKey().serialize()))
// .build();
let keyId: UInt32 = 1
let unsignedServerCertificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId,
key: try! keyPair.ecPublicKey().serialized)
// SignalProtos.ServerCertificate.Certificate certificate = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(keyPair.getPublicKey().serialize()))
// .build();
let certificateBuilder = SMKProtoServerCertificateCertificate.builder(id: 1,
key: try! keyPair.ecPublicKey().serialized)
// byte[] certificateBytes = certificate.toByteArray();
let certificateData = try! certificateBuilder.build().serializedData()
// byte[] certificateBytes = certificate.toByteArray();
let unsignedServerCertificateData = try! unsignedServerCertificateBuilder.build().serializedData()
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: trustRoot)
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let serverCertificateSignature = try! Ed25519.sign(unsignedServerCertificateData, with: trustRoot)
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build().toByteArray();
//
let serializedData = try! SMKProtoServerCertificate.builder(certificate: certificateData,
signature: certificateSignature)
.buildSerializedData()
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build().toByteArray();
let signedServerCertificate = SMKServerCertificate(keyId: keyId,
key: try! keyPair.ecPublicKey(),
signatureData: serverCertificateSignature)
let serializedData = try! signedServerCertificate.serialized()
let parsed = try! SMKServerCertificate.parse(data: serializedData)
// new CertificateValidator(trustRoot.getPublicKey()).validate(new ServerCertificate(serialized));
// new CertificateValidator(trustRoot.getPublicKey()).validate(new ServerCertificate(serialized));
let serverCertificate = try! SMKServerCertificate(serializedData: serializedData)
let certificateValidator = SMKCertificateDefaultValidator(trustRoot: try! trustRoot.ecPublicKey())
try! certificateValidator.throwswrapped_validate(serverCertificate: parsed)
try! certificateValidator.throwswrapped_validate(serverCertificate: serverCertificate)
}
// public void testBadSignature() throws Exception {
@ -96,77 +94,83 @@ class SMKServerCertificateTest: XCTestCase {
let trustRoot = Curve25519.generateKeyPair()
let keyPair = Curve25519.generateKeyPair()
// SignalProtos.ServerCertificate.Certificate certificate = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(keyPair.getPublicKey().serialize()))
// .build();
let keyId: UInt32 = 1
let unsignedServerCertificateBuilder = SMKProtoServerCertificateCertificate.builder(id: keyId,
key: try! keyPair.ecPublicKey().serialized)
// SignalProtos.ServerCertificate.Certificate certificate = SignalProtos.ServerCertificate.Certificate.newBuilder()
// .setId(1)
// .setKey(ByteString.copyFrom(keyPair.getPublicKey().serialize()))
// .build();
let certificate = try! SMKProtoServerCertificateCertificate.builder(id: 1,
key: try! keyPair.ecPublicKey().serialized)
.build()
// byte[] certificateBytes = certificate.toByteArray();
let unsignedServerCertificateData = try! unsignedServerCertificateBuilder.build().serializedData()
// byte[] certificateBytes = certificate.toByteArray();
let certificateData = try! certificate.serializedData()
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let serverCertificateSignature = try! Ed25519.sign(unsignedServerCertificateData, with: trustRoot)
// byte[] certificateSignature = Curve.calculateSignature(trustRoot.getPrivateKey(), certificateBytes);
let certificateSignature = try! Ed25519.sign(certificateData, with: trustRoot)
// for (int i=0;i<certificateSignature.length;i++) {
for i in 0..<serverCertificateSignature.count {
// for (int b=0;b<8;b++) {
// for (int i=0;i<certificateSignature.length;i++) {
// for (int b=0;b<8;b++) {
for i in 0..<certificateSignature.count {
for b in 0..<8 {
// byte[] badSignature = new byte[certificateSignature.length];
// System.arraycopy(certificateSignature, 0, badSignature, 0, badSignature.length);
var badSignature = serverCertificateSignature
// badSignature[i] = (byte) (badSignature[i] ^ (1 << b));
badSignature.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
bytes[i] = (UInt8)(bytes[i] ^ 1 << b)
// byte[] badSignature = new byte[certificateSignature.length];
// System.arraycopy(certificateSignature, 0, badSignature, 0, badSignature.length);
//
// badSignature[i] = (byte) (badSignature[i] ^ (1 << b));
var badSignature = certificateSignature
badSignature.withUnsafeMutableBytes { (bytes: UnsafeMutableRawBufferPointer) in
bytes[i] = (bytes[i] ^ 1 << b)
}
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(badSignature))
// .build().toByteArray();
let signedServerCertificate = SMKServerCertificate(keyId: keyId,
key: try! keyPair.ecPublicKey(),
signatureData: badSignature)
let serializedData = try! signedServerCertificate.serialized()
let parsed = try! SMKServerCertificate.parse(data: serializedData)
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(certificateBytes))
// .setSignature(ByteString.copyFrom(badSignature))
// .build().toByteArray();
let serializedData = try! SMKProtoServerCertificate.builder(certificate: certificateData,
signature: badSignature)
.buildSerializedData()
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(new ServerCertificate(serialized));
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(new ServerCertificate(serialized));
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
let serverCertificate = try! SMKServerCertificate(serializedData: serializedData)
let certificateValidator = SMKCertificateDefaultValidator(trustRoot: try! trustRoot.ecPublicKey())
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(serverCertificate: parsed))
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(serverCertificate: serverCertificate))
}
}
// for (int i=0;i<certificateBytes.length;i++) {
for i in 0..<unsignedServerCertificateData.count {
// for (int b=0;b<8;b++) {
// for (int i=0;i<certificateBytes.length;i++) {
// for (int b=0;b<8;b++) {
for i in 0..<certificateData.count {
for b in 0..<8 {
// byte[] badCertificate = new byte[certificateBytes.length];
// System.arraycopy(certificateBytes, 0, badCertificate, 0, badCertificate.length);
var badCertificate = unsignedServerCertificateData
// badCertificate[i] = (byte) (badCertificate[i] ^ (1 << b));
badCertificate.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
bytes[i] = (UInt8)(bytes[i] ^ 1 << b)
// byte[] badCertificate = new byte[certificateBytes.length];
// System.arraycopy(certificateBytes, 0, badCertificate, 0, badCertificate.length);
//
// badCertificate[i] = (byte) (badCertificate[i] ^ (1 << b));
var badCertificate = certificateData
badCertificate.withUnsafeMutableBytes { (bytes: UnsafeMutableRawBufferPointer) in
bytes[i] = (bytes[i] ^ 1 << b)
}
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(badCertificate))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build().toByteArray();
let builder =
SMKProtoServerCertificate.builder(certificate: badCertificate, signature: serverCertificateSignature)
let serializedData = try! builder.buildSerializedData()
let parsed: SMKServerCertificate
// byte[] serialized = SignalProtos.ServerCertificate.newBuilder()
// .setCertificate(ByteString.copyFrom(badCertificate))
// .setSignature(ByteString.copyFrom(certificateSignature))
// .build().toByteArray();
let serializedData = try! SMKProtoServerCertificate.builder(certificate: badCertificate,
signature: certificateSignature)
.buildSerializedData()
// try {
// new CertificateValidator(trustRoot.getPublicKey()).validate(new ServerCertificate(serialized));
// throw new AssertionError();
// } catch (InvalidCertificateException e) {
// // good
// }
let serverCertificate: SMKServerCertificate
do {
parsed = try SMKServerCertificate.parse(data: serializedData)
serverCertificate = try SMKServerCertificate(serializedData: serializedData)
} catch BinaryDecodingError.malformedProtobuf {
// Some bad certificates will fail to parse.
continue
@ -192,7 +196,7 @@ class SMKServerCertificateTest: XCTestCase {
// }
// }
let certificateValidator = SMKCertificateDefaultValidator(trustRoot: try! trustRoot.ecPublicKey())
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(serverCertificate: parsed))
XCTAssertThrowsError(try certificateValidator.throwswrapped_validate(serverCertificate: serverCertificate))
}
}
}