static void readRecipientInfo(List infos, KeyAgreeRecipientInfo info, AlgorithmIdentifier messageAlgorithm, CMSSecureReadable secureReadable, AuthAttributesProvider additionalData) { ASN1Sequence s = info.getRecipientEncryptedKeys(); for (int i = 0; i < s.size(); ++i) { RecipientEncryptedKey id = RecipientEncryptedKey.getInstance( s.getObjectAt(i)); RecipientId rid; KeyAgreeRecipientIdentifier karid = id.getIdentifier(); IssuerAndSerialNumber iAndSN = karid.getIssuerAndSerialNumber(); if (iAndSN != null) { rid = new KeyAgreeRecipientId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); } else { RecipientKeyIdentifier rKeyID = karid.getRKeyID(); // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational rid = new KeyAgreeRecipientId(rKeyID.getSubjectKeyIdentifier().getOctets()); } infos.add(new KeyAgreeRecipientInformation(info, rid, id.getEncryptedKey(), messageAlgorithm, secureReadable, additionalData)); } }
/** * Add a recipient based on the passed in certificate's public key and its issuer and serial number. * * @param recipientCert recipient's certificate * @return the current instance. * @throws CertificateEncodingException if the necessary data cannot be extracted from the certificate. */ public JceKeyAgreeRecipientInfoGenerator addRecipient(X509Certificate recipientCert) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(CMSUtils.getIssuerAndSerialNumber(recipientCert))); recipientKeys.add(recipientCert.getPublicKey()); return this; }
/** * Add a recipient identified by the passed in subjectKeyID and the for the passed in public key. * * @param subjectKeyID identifier actual recipient will use to match the private key. * @param publicKey the public key for encrypting the secret key. * @return the current instance. * @throws CertificateEncodingException */ public JceKeyAgreeRecipientInfoGenerator addRecipient(byte[] subjectKeyID, PublicKey publicKey) throws CertificateEncodingException { recipientIDs.add(new KeyAgreeRecipientIdentifier(new RecipientKeyIdentifier(subjectKeyID))); recipientKeys.add(publicKey); return this; }
public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) throws CMSException { if (recipientIDs.isEmpty()) { throw new CMSException("No recipients associated with generator - use addRecipient()"); } init(keyAgreeAlgorithm.getAlgorithm()); PrivateKey senderPrivateKey = this.senderPrivateKey; ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); ASN1EncodableVector recipientEncryptedKeys = new ASN1EncodableVector(); for (int i = 0; i != recipientIDs.size(); i++) { PublicKey recipientPublicKey = (PublicKey)recipientKeys.get(i); KeyAgreeRecipientIdentifier karId = (KeyAgreeRecipientIdentifier)recipientIDs.get(i); try { AlgorithmParameterSpec agreementParamSpec; if (CMSUtils.isMQV(keyAgreementOID)) { agreementParamSpec = new MQVParameterSpec(ephemeralKP, recipientPublicKey, userKeyingMaterial); } else if (CMSUtils.isEC(keyAgreementOID)) { byte[] ukmKeyingMaterial = ecc_cms_Generator.generateKDFMaterial(keyEncryptionAlgorithm, keySizeProvider.getKeySize(keyEncryptionAlgorithm.getAlgorithm()), userKeyingMaterial); agreementParamSpec = new UserKeyingMaterialSpec(ukmKeyingMaterial); } else if (CMSUtils.isRFC2631(keyAgreementOID)) { if (userKeyingMaterial != null) { agreementParamSpec = new UserKeyingMaterialSpec(userKeyingMaterial); } else { if (keyAgreementOID.equals(PKCSObjectIdentifiers.id_alg_SSDH)) { throw new CMSException("User keying material must be set for static keys."); } agreementParamSpec = null; } } else { throw new CMSException("Unknown key agreement algorithm: " + keyAgreementOID); } // Use key agreement to choose a wrap key for this recipient KeyAgreement keyAgreement = helper.createKeyAgreement(keyAgreementOID); keyAgreement.init(senderPrivateKey, agreementParamSpec, random); keyAgreement.doPhase(recipientPublicKey, true); SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncryptionAlgorithm.getAlgorithm().getId()); // Wrap the content encryption key with the agreement key Cipher keyEncryptionCipher = helper.createCipher(keyEncryptionAlgorithm.getAlgorithm()); keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey)); ASN1OctetString encryptedKey = new DEROctetString(encryptedKeyBytes); recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, encryptedKey)); } catch (GeneralSecurityException e) { throw new CMSException("Cannot perform agreement step: " + e.getMessage(), e); } } return new DERSequence(recipientEncryptedKeys); }