1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package org.spongycastle.cms;
import java.io.IOException;
import java.util.List;
import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
import org.spongycastle.asn1.cms.KeyAgreeRecipientIdentifier;
import org.spongycastle.asn1.cms.KeyAgreeRecipientInfo;
import org.spongycastle.asn1.cms.OriginatorIdentifierOrKey;
import org.spongycastle.asn1.cms.OriginatorPublicKey;
import org.spongycastle.asn1.cms.RecipientEncryptedKey;
import org.spongycastle.asn1.cms.RecipientKeyIdentifier;
import org.spongycastle.asn1.x509.AlgorithmIdentifier;
import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
import org.spongycastle.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());
}
}
|