Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit d0f1811

Browse files
committed
FAB-4532 Signature algorithm wrong for endorsers
Change-Id: I7e0e019f62575180fa38dd5b211f5105e87f29a7 Signed-off-by: rickr <cr22rc@gmail.com>
1 parent bedc97c commit d0f1811

File tree

4 files changed

+74
-96
lines changed

4 files changed

+74
-96
lines changed

src/main/java/org/hyperledger/fabric/sdk/ProposalResponse.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,9 @@ public boolean verify(CryptoSuite crypto) {
9898
logger.trace("plainText bytes in hex: " + DatatypeConverter.printHexBinary(plainText.toByteArray()));
9999
}
100100

101-
this.isVerified = crypto.verify(plainText.toByteArray(), sig.toByteArray(),
102-
endorser.getIdBytes().toByteArray());
101+
this.isVerified = crypto.verify(endorser.getIdBytes().toByteArray(), config.getSignatureAlgorithm(),
102+
sig.toByteArray(), plainText.toByteArray()
103+
);
103104
} catch (InvalidProtocolBufferException | CryptoException e) {
104105
logger.error("verify: Cannot retrieve peer identity from ProposalResponse. Error is: " + e.getMessage(), e);
105106
this.isVerified = false;

src/main/java/org/hyperledger/fabric/sdk/security/CryptoPrimitives.java

Lines changed: 27 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ public class CryptoPrimitives implements CryptoSuite {
9393

9494
// Following configuration settings are hardcoded as they don't deal with any interactions with Fabric MSP and BCCSP components
9595
// If you wish to make these customizable, follow the logic from setProperties();
96-
private String ASYMMETRIC_KEY_TYPE = "EC";
97-
private String KEY_AGREEMENT_ALGORITHM = "ECDH";
98-
private String SYMMETRIC_KEY_TYPE = "AES";
99-
private int SYMMETRIC_KEY_BYTE_COUNT = 32;
100-
private String SYMMETRIC_ALGORITHM = "AES/CFB/NoPadding";
101-
private int MAC_KEY_BYTE_COUNT = 32;
96+
//TODO May need this for TCERTS ?
97+
// private String ASYMMETRIC_KEY_TYPE = "EC";
98+
// private String KEY_AGREEMENT_ALGORITHM = "ECDH";
99+
// private String SYMMETRIC_KEY_TYPE = "AES";
100+
// private int SYMMETRIC_KEY_BYTE_COUNT = 32;
101+
// private String SYMMETRIC_ALGORITHM = "AES/CFB/NoPadding";
102+
// private int MAC_KEY_BYTE_COUNT = 32;
102103

103104
private static final Log logger = LogFactory.getLog(CryptoPrimitives.class);
104105

@@ -148,17 +149,12 @@ public Certificate bytesToCertificate(byte[] certBytes) throws CryptoException {
148149
}
149150

150151
/**
151-
* Verify a signature.
152-
*
153-
* @param plainText original text.
154-
* @param signature signature value as a byte array.
155-
* @param pemCertificate the X509 certificate to be used for verification
156-
* @return {@code true} if the signature was successfully verified; otherwise {@code false}.
157-
* @throws CryptoException
152+
* @inheritDoc
158153
*/
154+
159155
@Override
160-
public boolean verify(byte[] plainText, byte[] signature, byte[] pemCertificate) throws CryptoException {
161-
boolean isVerified = false;
156+
public boolean verify(byte[] pemCertificate, String signatureAlgorithm, byte[] signature, byte[] plainText) throws CryptoException {
157+
boolean isVerified;
162158

163159
if (plainText == null || signature == null || pemCertificate == null) {
164160
return false;
@@ -176,24 +172,14 @@ public boolean verify(byte[] plainText, byte[] signature, byte[] pemCertificate)
176172
BufferedInputStream pem = new BufferedInputStream(new ByteArrayInputStream(pemCertificate));
177173
CertificateFactory certFactory = CertificateFactory.getInstance(CERTIFICATE_FORMAT);
178174
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(pem);
175+
179176
isVerified = validateCertificate(certificate);
180177
if (isVerified) { // only proceed if cert is trusted
181-
String signatureAlgorithm = certificate.getSigAlgName();
178+
182179
Signature sig = Signature.getInstance(signatureAlgorithm);
183180
sig.initVerify(certificate);
184181
sig.update(plainText);
185182
isVerified = sig.verify(signature);
186-
if (!isVerified) {
187-
// TODO currently fabric is trying to decide if the signature algorithm should
188-
// be passed along inside the certificate or configured manually or included in
189-
// the message itself. fabric-ca is also about to align its defaults with fabric.
190-
// while we wait, we will try both the algorithm specified in the cert and the
191-
// hardcoded default from fabric/fabric-ca
192-
sig = Signature.getInstance(DEFAULT_SIGNATURE_ALGORITHM);
193-
sig.initVerify(certificate);
194-
sig.update(plainText);
195-
isVerified = sig.verify(signature);
196-
}
197183
}
198184
} catch (InvalidKeyException | CertificateException e) {
199185
CryptoException ex = new CryptoException("Cannot verify signature. Error is: "
@@ -229,7 +215,7 @@ private void createTrustStore() throws CryptoException {
229215
* @param keyStore the KeyStore which will be used to hold trusted certificates
230216
* @throws InvalidArgumentException
231217
*/
232-
public void setTrustStore(KeyStore keyStore) throws InvalidArgumentException {
218+
void setTrustStore(KeyStore keyStore) throws InvalidArgumentException {
233219

234220
if (keyStore == null) {
235221
throw new InvalidArgumentException("Need to specify a java.security.KeyStore input parameter");
@@ -286,7 +272,7 @@ public void addCACertificateToTrustStore(File caCertPem, String alias) throws Cr
286272
* @throws CryptoException
287273
* @throws InvalidArgumentException
288274
*/
289-
public void addCACertificateToTrustStore(Certificate caCert, String alias) throws InvalidArgumentException, CryptoException {
275+
void addCACertificateToTrustStore(Certificate caCert, String alias) throws InvalidArgumentException, CryptoException {
290276

291277
if (alias == null || alias.isEmpty()) {
292278
throw new InvalidArgumentException("You must assign an alias to a certificate when adding to the trust store.");
@@ -348,7 +334,7 @@ public void loadCACertificatesAsBytes(Collection<byte[]> certificatesBytes) thro
348334
* @param certPEM the certificate in PEM format
349335
* @return true if the certificate is trusted
350336
*/
351-
public boolean validateCertificate(byte[] certPEM) {
337+
boolean validateCertificate(byte[] certPEM) {
352338

353339
if (certPEM == null) {
354340
return false;
@@ -366,11 +352,11 @@ public boolean validateCertificate(byte[] certPEM) {
366352
}
367353
}
368354

369-
public boolean validateCertificate(Certificate cert) {
370-
boolean isValidated = false;
355+
boolean validateCertificate(Certificate cert) {
356+
boolean isValidated;
371357

372358
if (cert == null) {
373-
return isValidated;
359+
return false;
374360
}
375361

376362
try {
@@ -384,7 +370,7 @@ public boolean validateCertificate(Certificate cert) {
384370

385371
CertPathValidator certValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType()); // PKIX
386372

387-
ArrayList<Certificate> start = new ArrayList<Certificate>();
373+
ArrayList<Certificate> start = new ArrayList<>();
388374
start.add(cert);
389375
CertificateFactory certFactory = CertificateFactory.getInstance(CERTIFICATE_FORMAT);
390376
CertPath certPath = certFactory.generateCertPath(start);
@@ -401,17 +387,13 @@ public boolean validateCertificate(Certificate cert) {
401387
return isValidated;
402388
} // validateCertificate
403389

404-
public int getSecurityLevel() {
405-
return securityLevel;
406-
}
407-
408390
/**
409391
* Security Level determines the elliptic curve used in key generation
410392
*
411393
* @param securityLevel currently 256 or 384
412394
* @throws InvalidArgumentException
413395
*/
414-
public void setSecurityLevel(int securityLevel) throws InvalidArgumentException {
396+
void setSecurityLevel(int securityLevel) throws InvalidArgumentException {
415397
if (securityLevel != 256 && securityLevel != 384) {
416398
throw new InvalidArgumentException("Illegal level: " + securityLevel + " must be either 256 or 384");
417399
}
@@ -424,11 +406,7 @@ public void setSecurityLevel(int securityLevel) throws InvalidArgumentException
424406
}
425407
}
426408

427-
public String getHashAlgorithm() {
428-
return this.hashAlgorithm;
429-
}
430-
431-
public void setHashAlgorithm(String algorithm) throws InvalidArgumentException {
409+
void setHashAlgorithm(String algorithm) throws InvalidArgumentException {
432410
if (Utils.isNullOrEmpty(algorithm)
433411
|| !(algorithm.equalsIgnoreCase("SHA2") || algorithm.equalsIgnoreCase("SHA3"))) {
434412
throw new InvalidArgumentException("Illegal Hash function family: "
@@ -452,8 +430,7 @@ private KeyPair generateKey(String encryptionName, String curveName) throws Cryp
452430
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec(curveName);
453431
KeyPairGenerator g = KeyPairGenerator.getInstance(encryptionName, SECURITY_PROVIDER);
454432
g.initialize(ecGenSpec, new SecureRandom());
455-
KeyPair pair = g.generateKeyPair();
456-
return pair;
433+
return g.generateKeyPair();
457434
} catch (Exception exp) {
458435
throw new CryptoException("Unable to generate key pair", exp);
459436
}
@@ -579,7 +556,7 @@ private KeyPair generateKey(String encryptionName, String curveName) throws Cryp
579556
* @return the signed data.
580557
* @throws CryptoException
581558
*/
582-
public byte[] ecdsaSignToBytes(ECPrivateKey privateKey, byte[] data) throws CryptoException {
559+
private byte[] ecdsaSignToBytes(ECPrivateKey privateKey, byte[] data) throws CryptoException {
583560
try {
584561
final byte[] encoded = hash(data);
585562

@@ -606,8 +583,7 @@ public byte[] ecdsaSignToBytes(ECPrivateKey privateKey, byte[] data) throws Cryp
606583
seq.addObject(new ASN1Integer(sigs[0]));
607584
seq.addObject(new ASN1Integer(sigs[1]));
608585
seq.close();
609-
byte[] ret = s.toByteArray();
610-
return ret;
586+
return s.toByteArray();
611587

612588
} catch (Exception e) {
613589
throw new CryptoException("Could not sign the message using private key", e);
@@ -817,9 +793,9 @@ public Properties getProperties() {
817793
return properties;
818794
}
819795

820-
public byte[] certificateToDER(String certricatePEM) {
796+
public byte[] certificateToDER(String certificatePEM) {
821797

822-
try (PemReader pemReader = new PemReader(new StringReader(certricatePEM))) {
798+
try (PemReader pemReader = new PemReader(new StringReader(certificatePEM))) {
823799
final PemObject pemObject = pemReader.readPemObject();
824800
return pemObject.getContent();
825801

src/main/java/org/hyperledger/fabric/sdk/security/CryptoSuite.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ public interface CryptoSuite {
8686
/**
8787
* Verify the specified signature
8888
*
89-
* @param plainText the original text
90-
* @param signature the signature to verify
9189
* @param certificate the certificate of the signer as the contents of the PEM file
90+
* @param signatureAlgorithm the algorithm used to create the signature.
91+
* @param signature the signature to verify
92+
* @param plainText the original text that is to be verified
9293
* @return {@code true} if the signature is successfully verified; otherwise {@code false}.
9394
* @throws CryptoException
9495
*/
95-
boolean verify(byte[] plainText, byte[] signature, byte[] certificate) throws CryptoException;
96+
boolean verify(byte[] certificate, String signatureAlgorithm, byte[] signature, byte[] plainText) throws CryptoException;
9697

9798
/**
9899
* Hash the specified text byte data.

0 commit comments

Comments
 (0)