| package org.bouncycastle.cms; |
| |
| import java.io.IOException; |
| import java.util.List; |
| |
| import org.bouncycastle.asn1.ASN1OctetString; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; |
| import org.bouncycastle.asn1.cms.KeyAgreeRecipientIdentifier; |
| import org.bouncycastle.asn1.cms.KeyAgreeRecipientInfo; |
| import org.bouncycastle.asn1.cms.OriginatorIdentifierOrKey; |
| import org.bouncycastle.asn1.cms.OriginatorPublicKey; |
| import org.bouncycastle.asn1.cms.RecipientEncryptedKey; |
| import org.bouncycastle.asn1.cms.RecipientKeyIdentifier; |
| import org.bouncycastle.asn1.x509.AlgorithmIdentifier; |
| import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; |
| import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; |
| |
| /** |
| * the RecipientInfo class for a recipient who has been sent a message |
| * encrypted using key agreement. |
| */ |
| public class KeyAgreeRecipientInformation |
| extends RecipientInformation |
| { |
| private KeyAgreeRecipientInfo info; |
| private ASN1OctetString encryptedKey; |
| |
| 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)); |
| } |
| } |
| |
| KeyAgreeRecipientInformation( |
| KeyAgreeRecipientInfo info, |
| RecipientId rid, |
| ASN1OctetString encryptedKey, |
| AlgorithmIdentifier messageAlgorithm, |
| CMSSecureReadable secureReadable, |
| AuthAttributesProvider additionalData) |
| { |
| super(info.getKeyEncryptionAlgorithm(), messageAlgorithm, secureReadable, additionalData); |
| |
| this.info = info; |
| this.rid = rid; |
| this.encryptedKey = encryptedKey; |
| } |
| |
| private SubjectPublicKeyInfo getSenderPublicKeyInfo(AlgorithmIdentifier recKeyAlgId, |
| OriginatorIdentifierOrKey originator) |
| throws CMSException, IOException |
| { |
| OriginatorPublicKey opk = originator.getOriginatorKey(); |
| if (opk != null) |
| { |
| return getPublicKeyInfoFromOriginatorPublicKey(recKeyAlgId, opk); |
| } |
| |
| OriginatorId origID; |
| |
| IssuerAndSerialNumber iAndSN = originator.getIssuerAndSerialNumber(); |
| if (iAndSN != null) |
| { |
| origID = new OriginatorId(iAndSN.getName(), iAndSN.getSerialNumber().getValue()); |
| } |
| else |
| { |
| SubjectKeyIdentifier ski = originator.getSubjectKeyIdentifier(); |
| |
| origID = new OriginatorId(ski.getKeyIdentifier()); |
| } |
| |
| return getPublicKeyInfoFromOriginatorId(origID); |
| } |
| |
| private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorPublicKey(AlgorithmIdentifier recKeyAlgId, |
| OriginatorPublicKey originatorPublicKey) |
| { |
| SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo( |
| recKeyAlgId, |
| originatorPublicKey.getPublicKey().getBytes()); |
| |
| return pubInfo; |
| } |
| |
| private SubjectPublicKeyInfo getPublicKeyInfoFromOriginatorId(OriginatorId origID) |
| throws CMSException |
| { |
| // TODO Support all alternatives for OriginatorIdentifierOrKey |
| // see RFC 3852 6.2.2 |
| throw new CMSException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier"); |
| } |
| |
| protected RecipientOperator getRecipientOperator(Recipient recipient) |
| throws CMSException, IOException |
| { |
| KeyAgreeRecipient agreeRecipient = (KeyAgreeRecipient)recipient; |
| AlgorithmIdentifier recKeyAlgId = agreeRecipient.getPrivateKeyAlgorithmIdentifier(); |
| |
| return ((KeyAgreeRecipient)recipient).getRecipientOperator(keyEncAlg, messageAlgorithm, getSenderPublicKeyInfo(recKeyAlgId, |
| info.getOriginator()), info.getUserKeyingMaterial(), encryptedKey.getOctets()); |
| } |
| } |