iaik.smime.ess
Class Receipt
java.lang.Object
iaik.smime.ess.Receipt
- All Implemented Interfaces:
- Content, ContentStream
public class Receipt
- extends java.lang.Object
- implements Content
The S/MIMEv3 ESS Receipt content type.
The Enhanced Security Services
for S/MIMEv3 (ESS) (RFC 2634) specifies the Receipt
content type to be set as content of a SignedData
which shall be sent in response to a ReceiptRequest
received:
Receipt ::= SEQUENCE {
version ESSVersion,
contentType ContentType,
signedContentIdentifier ContentIdentifier,
originatorSignatureValue OCTET STRING }
id-ct-receipt OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-ct(1) 1}
ESSVersion ::= INTEGER { v1(1) }
When receiving a SignedData
having any
SignerInfo
holding a ReceiptRequest
the recipient first has to check
if all ReceiptRequests contained in any of the SignerInfos are
identical. According to the rules given in
RFC 2634, section 2.3,
the recipient then checks if it is requested to create signed
receipt(s) to be sent to dedicated user(s). If a signed
receipt has to be sent, the recipient performs the following
steps for creating the signed receipt and setting it as
content of a SignedData object ("signedData/Receipt", see
RFC 2634, section 2.4):
- The signature of the original signedData signerInfo that includes
the receiptRequest signed attribute MUST be successfully verified
before creating the signedData/Receipt.
- The content of the original signedData object is digested as
described in CMS (RFC 5652).
The resulting digest value is then compared with the value
of the messageDigest attribute included in the signedAttributes
of the original signedData signerInfo. If these digest values
are different, then the signature verification process fails and
the signedData/Receipt MUST NOT be created.
- The ASN.1 DER encoded signedAttributes (including
messageDigest, receiptRequest and, possibly, other signed
attributes) in the original signedData signerInfo are
digested as described in CMS
(RFC 5652).
The resulting digest value, called msgSigDigest, is then used to verify
the signature of the original signedData signerInfo. If the signature
verification fails, then the signedData/Receipt MUST NOT be created.
- A Receipt structure is created.
- The value of the Receipt version field is set to 1.
- The object identifier from the contentType attribute
included in the original signedData signerInfo that
includes the receiptRequest attribute is copied into
the Receipt contentType.
- The original signedData signerInfo receiptRequest
signedContentIdentifier is copied into the Receipt
signedContentIdentifier.
- The signature value from the original signedData signerInfo
that includes the receiptRequest attribute is copied into
the Receipt originatorSignatureValue.
- The Receipt structure is ASN.1 DER encoded to produce a data
stream, D1.
- D1 is digested. The resulting digest value is included as the
messageDigest attribute in the signedAttributes of the signerInfo
which will eventually contain the signedData/Receipt signature
value.
- The digest value (msgSigDigest) calculated in Step 1 to verify the
signature of the original signedData signerInfo is included as the
msgSigDigest attribute in the signedAttributes of the signerInfo
which will eventually contain the signedData/Receipt signature
value.
- A contentType attribute including the id-ct-receipt object
identifier MUST be created and added to the signed attributes of
the signerInfo which will eventually contain the
signedData/Receipt signature value.
- A signingTime attribute indicating the time that the
signedData/Receipt is signed SHOULD be created and added to the
signed attributes of the signerInfo which will eventually contain
the signedData/Receipt signature value. Other attributes (except
receiptRequest) may be added to the signedAttributes of the
signerInfo.
- The signedAttributes (messageDigest, msgSigDigest, contentType and,
possibly, others) of the signerInfo are ASN.1 DER encoded and
digested as described in CMS
(RFC 5652).
The resulting digest value is used to calculate the signature value
which is then included in the signedData/Receipt signerInfo.
- The ASN.1 DER encoded Receipt content MUST be directly encoded
within the signedData encapContentInfo eContent OCTET STRING
defined in CMS
(RFC 5652).
The id-ct-receipt object identifier MUST be included in the signedData
encapContentInfo eContentType. This results in a single ASN.1
encoded object composed of a signedData including the Receipt
content. The Data content type MUST NOT be used. The Receipt
content MUST NOT be encapsulated in a MIME header or any other
header prior to being encoded as part of the signedData object.
- The signedData/Receipt is then put in an application/pkcs7-mime
MIME wrapper with the smime-type parameter set to
"signed-receipt". This will allow for identification of signed
receipts without having to crack the ASN.1 body. The smime-type
parameter would still be set as normal in any layer wrapped
around this message.
- If the signedData/Receipt is to be encrypted within an
envelopedData object, then an outer signedData object MUST be
created that encapsulates the envelopedData object, and a
contentHints attribute with contentType set to the id-ct-receipt
object identifier MUST be included in the outer signedData
SignerInfo signedAttributes. When a receiving agent processes the
outer signedData object, the presence of the id-ct-receipt OID in
the contentHints contentType indicates that a signedData/Receipt
is encrypted within the envelopedData object encapsulated by the
outer signedData.
When receiving a signed receipt the following steps have to be performed
for validating the signed receipt (see
RFC 2634, section 2.6):
- ASN.1 decode the signedData object including the Receipt content.
- Extract the contentType, signedContentIdentifier, and
originatorSignatureValue from the decoded Receipt structure to
identify the original signedData signerInfo that requested the
signedData/Receipt.
- Acquire the message signature digest value calculated by the sender
to generate the signature value included in the original signedData
signerInfo that requested the signedData/Receipt.
- If the sender-calculated message signature digest value has
been saved locally by the sender, it must be located and
retrieved.
- If it has not been saved, then it must be re-calculated based
on the original signedData content and signedAttributes as
described in CMS
(RFC 5652).
- The message signature digest value calculated by the sender is then
compared with the value of the msgSigDigest signedAttribute
included in the signedData/Receipt signerInfo. If these digest
values are identical, then that proves that the message signature
digest value calculated by the recipient based on the received
original signedData object is the same as that calculated by the
sender. This proves that the recipient received exactly the same
original signedData content and signedAttributes as sent by the
sender because that is the only way that the recipient could have
calculated the same message signature digest value as calculated by
the sender. If the digest values are different, then the
signedData/Receipt signature verification process fails.
- Acquire the digest value calculated by the sender for the Receipt
content constructed by the sender (including the contentType,
signedContentIdentifier, and signature value that were included in
the original signedData signerInfo that requested the
signedData/Receipt).
- If the sender-calculated Receipt content digest value has
been saved locally by the sender, it must be located and
retrieved.
- If it has not been saved, then it must be re-calculated. As
described in section above, step 2, create a Receipt
structure including the contentType, signedContentIdentifier
and signature value that were included in the original
signedData signerInfo that requested the signed receipt. The
Receipt structure is then ASN.1 DER encoded to produce a data
stream which is then digested to produce the Receipt content
digest value.
- The Receipt content digest value calculated by the sender is then
compared with the value of the messageDigest signedAttribute
included in the signedData/Receipt signerInfo. If these digest
values are identical, then that proves that the values included in
the Receipt content by the recipient are identical to those that
were included in the original signedData signerInfo that requested
the signedData/Receipt. This proves that the recipient received the
original signedData signed by the sender, because that is the only
way that the recipient could have obtained the original signedData
signerInfo signature value for inclusion in the Receipt content. If
the digest values are different, then the signedData/Receipt
signature verification process fails.
- The ASN.1 DER encoded signedAttributes of the signedData/Receipt
signerInfo are digested as described in CMS
(RFC 5652).
- The resulting digest value is then used to verify the signature
value included in the signedData/Receipt signerInfo. If the
signature verification is successful, then that proves the
integrity of the signedData/receipt signerInfo signedAttributes and
authenticates the identity of the signer of the signedData/Receipt
signerInfo. Note that the signedAttributes include the
recipient-calculated Receipt content digest value (messageDigest
attribute) and recipient-calculated message signature digest value
(msgSigDigest attribute). Therefore, the aforementioned comparison
of the sender-generated and recipient-generated digest values
combined with the successful signedData/Receipt signature
verification proves that the recipient received the exact original
signedData content and signedAttributes (proven by msgSigDigest
attribute) that were signed by the sender of the original
signedData object (proven by messageDigest attribute). If the
signature verification fails, then the signedData/Receipt signature
verification process fails.
When creating
a new Receipt you may specify the content type, signed content
identifier and originator signature value immediately:
ObjectID contentType = ...;
ContentIdentifier contentIdentifier = ...;
byte[] originatorSignatureValue = ...;
Receipt Receipt =
new Receipt(contentType, contentIdentifier, originatorSignatureValue);
Or you may create
a Receipt from a SignerInfo
letting the constructor get the required information from the SignerInfo
to set the fields of the Receipt as required:
SignerInfo signerInfo = ...;
Receipt receipt = new Receipt(signerInfo);
- See Also:
ReceiptRequest
,
ContentIdentifier
,
SignerInfo
,
SignedData
Field Summary |
static ObjectID |
oid
The content type object identifier of the Receipt structure. |
Constructor Summary |
Receipt()
Empty default constructor. |
Receipt(ASN1Object obj)
Creates an Receipt from its ASN.1 representation. |
Receipt(java.io.InputStream is)
Creates a Receipt from an input stream supplying the DER encoded Receipt. |
Receipt(ObjectID contentType,
ContentIdentifier signedContentIdentifier,
byte[] originatorSignatureValue)
Creates an Receipt from given content type,
content identifier and originator signature value. |
Receipt(SignerInfo signerInfo)
Creates an Receipt from the given SignerInfo. |
Methods inherited from class java.lang.Object |
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
oid
public static final ObjectID oid
- The content type object identifier of the
Receipt
structure.
The corresponding OID string is "1.2.840.113549.1.9.16.1.1".
Receipt
public Receipt()
- Empty default constructor.
Required for dynamic object creation. Shall NOT be used by
an application.
Receipt
public Receipt(ObjectID contentType,
ContentIdentifier signedContentIdentifier,
byte[] originatorSignatureValue)
- Creates an Receipt from given content type,
content identifier and originator signature value.
- Parameters:
contentType
- the content type of the of the SignedData
to be linked tosignedContentIdentifier
- the signed content identifier
of the SignedData to be linked tooriginatorSignatureValue
- the signature value of the
SignedData to be linked to
Receipt
public Receipt(SignerInfo signerInfo)
throws ESSException
- Creates an Receipt from the given SignerInfo.
This constructor follows the instructions given in
RFC 2634, section 2.4, 2:
- The value of the Receipt version field is set to 1.
- The object identifier from the contentType attribute
included in the original signedData signerInfo that
includes the receiptRequest attribute is copied into
the Receipt contentType.
- The original signedData signerInfo receiptRequest
signedContentIdentifier is copied into the Receipt
signedContentIdentifier.
- The signature value from the original signedData signerInfo
that includes the receiptRequest attribute is copied into
the Receipt originatorSignatureValue.
This constructor just creates a Receipt as described above, but does
not perform any signature or ReceiptRequest validation.
- Parameters:
signerInfo
- the signerInfo from which to create a Receipt
- Throws:
ESSException
- if the Receipt cannot be created for some
reason, e.g. no ReceiptRequest is included in the
supplied SignerInfo
Receipt
public Receipt(java.io.InputStream is)
throws java.io.IOException,
CMSParsingException
- Creates a Receipt from an input stream supplying the DER encoded Receipt.
- Parameters:
is
- the input stream from where to read the encoded Receipt
- Throws:
CMSParsingException
- if the object cannot be paresd
java.io.IOException
- if an error occurs while reading from the stream
Receipt
public Receipt(ASN1Object obj)
throws CMSParsingException
- Creates an Receipt from its ASN.1 representation.
- Parameters:
obj
- the Receipt as ASN1Object
- Throws:
CMSParsingException
- if the object cannot be paresd
setSecurityProvider
public void setSecurityProvider(SecurityProvider securityProvider)
- Does nothing since no SecurityProvider is required by this class.
Only required to implement the
ContentStream
interface.
- Parameters:
securityProvider
- the SecurityProvider to be set; ignored
getSecurityProvider
public SecurityProvider getSecurityProvider()
- Returns null since no SecurityProvider is required by this class.
Only required to implement the
ContentStream
interface.
- Returns:
- null
getVersion
public int getVersion()
- Gets the ESSVersion number.
- Returns:
- the ESSVersion number (1) this Receipt conforms to
getBlockSize
public int getBlockSize()
- Returns -1.
Only implements the same name method of the
Content
interface, but has no meaning here.
- Specified by:
getBlockSize
in interface ContentStream
- Returns:
- -1
setBlockSize
public void setBlockSize(int blockSize)
- Does nothing.
Only implements the same name method of the
Content
interface., but has no meaning here.
- Specified by:
setBlockSize
in interface ContentStream
- Parameters:
blockSize
- the block size; ignored here
getReceiptContentType
public ObjectID getReceiptContentType()
- Returns the content type.
Attention! The OID returned by this method is the content
type as given in the second component of an Receipt object and
represents the value of the contentType attribute included in the
original signedData signerInfo that includes the receiptRequest:
Receipt ::= SEQUENCE {
version ESSVersion,
contentType ContentType,
signedContentIdentifier ContentIdentifier,
originatorSignatureValue OCTET STRING }
It has to be distinguished from the content type returned by
method getContentType
which always
returns the id-cd-receipt oid.
- Returns:
- the receipt content type
getSignedContentIdentifier
public ContentIdentifier getSignedContentIdentifier()
- Returns the signed content identifier.
- Returns:
- the signed content identifier
getOriginatorSignatureValue
public byte[] getOriginatorSignatureValue()
- Returns the originator signature value.
- Returns:
- the originator signature value
equals
public boolean equals(java.lang.Object obj)
- Compares this
Receipt
to the specified object.
- Overrides:
equals
in class java.lang.Object
- Parameters:
obj
- the object to compare this Receipt
against.
- Returns:
true
, if the given object is equal to this
Receipt
,
false
otherwise
hashCode
public int hashCode()
- Returns a hashcode for this
Receipt
.
- Overrides:
hashCode
in class java.lang.Object
- Returns:
- a hashcode for this
Receipt
decode
public void decode(java.io.InputStream is)
throws java.io.IOException,
CMSParsingException
- Reads and decodes a DER encoded Receipt from the given input stream.
- Specified by:
decode
in interface ContentStream
- Parameters:
is
- the input stream from where to read the encoded Receipt
- Throws:
CMSParsingException
- if the object cannot be paresd
java.io.IOException
- if an error occurs while reading from the stream
decode
public void decode(ASN1Object obj)
throws CMSParsingException
- Decodes the given ASN.1
Receipt
object for parsing
the internal structure.
- Specified by:
decode
in interface Content
- Parameters:
obj
- the Receipt as ASN1Object
- Throws:
CMSParsingException
- if the object cannot be paresd
toASN1Object
public ASN1Object toASN1Object()
- Returns this Receipt as ASN1Object.
- Specified by:
toASN1Object
in interface ContentStream
- Returns:
- this Receipt as ASN1Object
getContentType
public ObjectID getContentType()
- Returns the ESS Receipt (id-cd-receipt) content type object identifier.
Attention! This method implements the smae name method of
the Content
interface to always
return the id-ct-receipt oid.
The content type returned by this method has to be distinguished
from the content type returned by method getReceiptContentType()
which returns the content
type as given in the second component of an Receipt object:
Receipt ::= SEQUENCE {
version ESSVersion,
contentType ContentType,
signedContentIdentifier ContentIdentifier,
originatorSignatureValue OCTET STRING }
- Specified by:
getContentType
in interface ContentStream
- Returns:
- the ESS Receipt (id-cd-receipt) content type object identifier
toString
public java.lang.String toString()
- Returns a string representation of this Receipt.
- Overrides:
toString
in class java.lang.Object
- Returns:
- this Receipt as string
toString
public java.lang.String toString(boolean detailed)
- Returns a string representation of this Receipt.
- Specified by:
toString
in interface ContentStream
- Parameters:
detailed
- whether to give detailed information
- Returns:
- this Receipt as string
getEncoded
public byte[] getEncoded()
throws CMSException
- DER encodes this ESS
Receipt
object.
- Returns:
- the DER encoded Receipt object
- Throws:
CMSException
- if an encoding error occurs
writeTo
public void writeTo(java.io.OutputStream os)
throws java.io.IOException
- Writes this ESS
Receipt
object DER encoded to the given output stream.
- Parameters:
os
- the output stream to which to encode the Receipt
- Throws:
java.io.IOException
- if an error occurs during encoding to the stream
IAIK-CMS 6.0, (c) 2002 IAIK, (c) 2003, 2023 SIC