1.\" $OpenBSD: PKCS7_add_attribute.3,v 1.3 2020/06/10 11:39:12 schwarze Exp $ 2.\" 3.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: June 10 2020 $ 18.Dt PKCS7_ADD_ATTRIBUTE 3 19.Os 20.Sh NAME 21.Nm PKCS7_add_attribute , 22.Nm PKCS7_set_attributes , 23.Nm PKCS7_get_attribute , 24.Nm PKCS7_add_signed_attribute , 25.Nm PKCS7_set_signed_attributes , 26.Nm PKCS7_get_signed_attribute , 27.Nm PKCS7_add_attrib_content_type , 28.Nm PKCS7_add1_attrib_digest , 29.Nm PKCS7_add0_attrib_signing_time , 30.Nm PKCS7_add_attrib_smimecap 31.Nd attributes of SignerInfo objects 32.Sh SYNOPSIS 33.In openssl/pkcs7.h 34.Ft int 35.Fo PKCS7_add_attribute 36.Fa "PKCS7_SIGNER_INFO *si" 37.Fa "int nid" 38.Fa "int attrtype" 39.Fa "void *value" 40.Fc 41.Ft int 42.Fo PKCS7_set_attributes 43.Fa "PKCS7_SIGNER_INFO *si" 44.Fa "STACK_OF(X509_ATTRIBUTE) *sk" 45.Fc 46.Ft ASN1_TYPE * 47.Fo PKCS7_get_attribute 48.Fa "PKCS7_SIGNER_INFO *si" 49.Fa "int nid" 50.Fc 51.Ft int 52.Fo PKCS7_add_signed_attribute 53.Fa "PKCS7_SIGNER_INFO *si" 54.Fa "int nid" 55.Fa "int attrtype" 56.Fa "void *value" 57.Fc 58.Ft int 59.Fo PKCS7_set_signed_attributes 60.Fa "PKCS7_SIGNER_INFO *si" 61.Fa "STACK_OF(X509_ATTRIBUTE) *sk" 62.Fc 63.Ft ASN1_TYPE * 64.Fo PKCS7_get_signed_attribute 65.Fa "PKCS7_SIGNER_INFO *si" 66.Fa "int nid" 67.Fc 68.Ft int 69.Fo PKCS7_add_attrib_content_type 70.Fa "PKCS7_SIGNER_INFO *si" 71.Fa "ASN1_OBJECT *coid" 72.Fc 73.Ft int 74.Fo PKCS7_add1_attrib_digest 75.Fa "PKCS7_SIGNER_INFO *si" 76.Fa "const unsigned char *md" 77.Fa "int mdlen" 78.Fc 79.Ft int 80.Fo PKCS7_add0_attrib_signing_time 81.Fa "PKCS7_SIGNER_INFO *si" 82.Fa "ASN1_TIME *t" 83.Fc 84.Ft int 85.Fo PKCS7_add_attrib_smimecap 86.Fa "PKCS7_SIGNER_INFO *si" 87.Fa "STACK_OF(X509_ALGOR) *cap" 88.Fc 89.Sh DESCRIPTION 90.Fn PKCS7_add_attribute 91appends a new attribute of type 92.Fa nid 93to the 94.Fa unauthenticatedAttributes 95list of 96.Fa si , 97and it adds a new ASN.1 ANY object of type 98.Fa attrtype 99with the given 100.Fa value 101to the new attribute. 102Ownership of the 103.Fa value 104is transferred into the new attribute object, so the calling code 105must not 106.Xr free 3 107the 108.Fa value . 109If the list already contains an unauthenticated attribute of type 110.Fa nid 111before the call, the new attribute replaces the old one 112instead of being appended to the end of the list. 113.Pp 114.Fn PKCS7_set_attributes 115frees the 116.Fa unauthenticatedAttributes 117list of 118.Fa si 119and all the attributes contained in it and replaces it with a deep copy of 120.Fa sk . 121.Pp 122.Fn PKCS7_get_attribute 123retrieves the first ASN.1 ANY member of the attribute of type 124.Fa nid 125from the 126.Fa unauthenticatedAttributes 127list of 128.Fa si . 129.Pp 130The behaviour of 131.Fn PKCS7_add_signed_attribute , 132.Fn PKCS7_set_signed_attributes , 133and 134.Fn PKCS7_get_signed_attribute 135is identical except that they operate on the list of 136.Fa authenticatedAttributes . 137.Pp 138The normal way to use 139.Fn PKCS7_add_signed_attribute 140is to first create a 141.Vt SignedInfo 142object with 143.Xr PKCS7_sign 3 144using the 145.Dv PKCS7_PARTIAL 146or 147.Dv PKCS7_STREAM 148flag, retrieve the 149.Vt PKCS7_SIGNER_INFO 150object with 151.Xr PKCS7_get_signer_info 3 152or add an additional one with 153.Xr PKCS7_sign_add_signer 3 , 154call 155.Fn PKCS7_add_signed_attribute 156for each desired additional attribute, then do the signing with 157.Xr PKCS7_final 3 158or with another finalizing function. 159.Pp 160The four remaining functions are wrappers around 161.Fn PKCS7_add_signed_attribute . 162.Pp 163.Fn PKCS7_add_attrib_content_type 164sets the 165.Dv NID_pkcs9_contentType 166attribute to 167.Fa coid , 168which specifies the content type of the 169.Vt ContentInfo 170value to be signed. 171This attribute is mandatory and automatically added by 172.Xr PKCS7_sign 3 173and 174.Xr PKCS7_sign_add_signer 3 175unless the 176.Dv PKCS7_NOATTR 177flag is present. 178Objects suitable as 179.Fa coid 180arguments can for example be obtained with 181.Xr OBJ_nid2obj 3 . 182If 183.Fa coid 184is 185.Dv NULL , 186the content type defaults to 187.Dv NID_pkcs7_data . 188.Pp 189.Fn PKCS7_add1_attrib_digest 190sets or replaces the 191.Dv NID_pkcs9_messageDigest 192attribute, which is the message digest of the contents octets 193of the DER-encoding of the content field of the 194.Vt ContentInfo 195value being signed, to a copy of 196.Fa md , 197which is assumed to be 198.Fa mdlen 199bytes long. 200If 201.Fa mdlen 202is -1, then 203.Fn strlen md 204is used instead of 205.Fa mdlen . 206This attribute is mandatory and automatically added by 207.Xr PKCS7_dataFinal 3 208and 209.Xr PKCS7_final 3 . 210.Pp 211.Fn PKCS7_add0_attrib_signing_time 212sets or replaces the optional 213.Dv NID_pkcs9_signingTime 214attribute to 215.Fa t , 216specifying the time at which the signer performed the signing process. 217Ownership of 218.Fa t 219is transferred into the new attribute object, so the calling code 220must not 221.Xr free 3 222.Fa t . 223If 224.Fa t 225is 226.Dv NULL , 227a new 228.Vt ASN1_TIME 229structure is allocated. 230This attribute is automatically added by 231.Xr PKCS7_dataFinal 3 232and 233.Xr PKCS7_final 3 . 234.Pp 235.Fn PKCS7_add_attrib_smimecap 236sets or replaces the optional 237.Dv NID_SMIMECapabilities 238attribute, indicating algorithms the sender is prepared to handle. 239The 240.Fa cap 241pointer is not stored in the new attribute object and can be passed to 242.Fn sk_X509_ALGOR_pop_free 243after the call. 244This attribute is automatically added by 245.Xr PKCS7_sign 3 246and 247.Xr PKCS7_sign_add_signer 3 248unless the 249.Dv PKCS7_NOATTR 250or 251.Dv PKCS7_NOSMIMECAP 252flag is present. 253.Sh RETURN VALUES 254.Fn PKCS7_add_attribute , 255.Fn PKCS7_set_attributes , 256.Fn PKCS7_add_signed_attribute , 257.Fn PKCS7_set_signed_attributes , 258.Fn PKCS7_add_attrib_content_type , 259.Fn PKCS7_add1_attrib_digest , 260.Fn PKCS7_add0_attrib_signing_time , 261and 262.Fn PKCS7_add_attrib_smimecap 263return 1 on success or 0 on failure. 264The most common reason for failure is lack of memory. 265.Fn PKCS7_add_attribute 266and 267.Fn PKCS7_add_signed_attribute 268also fail if 269.Fa nid 270is invalid, and 271.Fn PKCS7_add_attrib_content_type 272if 273.Fa si 274already contains an authenticated attribute of type 275.Dv NID_pkcs9_contentType . 276.Pp 277.Fn PKCS7_get_attribute 278and 279.Fn PKCS7_get_signed_attribute 280return an internal pointer to an ASN.1 ANY object or 281.Dv NULL 282on failure. 283They fail if 284.Fa nid 285is invalid, if the respective list in 286.Fa si 287contains no attribute of the requested type, or if an invalid element 288is found in the list before finding the attribute of the requested type. 289.Sh SEE ALSO 290.Xr ASN1_TIME_new 3 , 291.Xr ASN1_TYPE_new 3 , 292.Xr OBJ_nid2obj 3 , 293.Xr PKCS7_final 3 , 294.Xr PKCS7_get_signer_info 3 , 295.Xr PKCS7_new 3 , 296.Xr PKCS7_sign 3 , 297.Xr PKCS7_sign_add_signer 3 , 298.Xr STACK_OF 3 , 299.Xr X509_ALGOR_new 3 , 300.Xr X509_ATTRIBUTE_new 3 301.Sh STANDARDS 302RFC 2315: PKCS #7: Cryptographic Message Syntax Version 1.5, 303section 9.2: SignerInfo type 304.Pp 305RFC 2985: PKCS #9: Selected Object Classes and Attribute Types Version 2.0, 306section 5.3: Attribute types for use in PKCS #7 data 307and section 5.6: Attributes defined in S/MIME 308.Pp 309RFC 8551: Secure/Multipurpose Internet Mail Extensions (S/MIME) 310Version 4.0 Message Specification, 311section 2.5.2: SMIMECapabilities Attribute 312.Sh HISTORY 313.Fn PKCS7_add_attribute , 314.Fn PKCS7_set_attributes , 315.Fn PKCS7_get_attribute , 316.Fn PKCS7_add_signed_attribute , 317.Fn PKCS7_set_signed_attributes , 318and 319.Fn PKCS7_get_signed_attribute 320first appeared in OpenSSL 0.9.1 and have been available since 321.Ox 2.6 . 322.Pp 323.Fn PKCS7_add_attrib_smimecap 324first appeared in OpenSSL 0.9.5 and has been available since 325.Ox 2.7 . 326.Pp 327.Fn PKCS7_add_attrib_content_type , 328.Fn PKCS7_add1_attrib_digest , 329and 330.Fn PKCS7_add0_attrib_signing_time 331first appeared in OpenSSL 1.0.0 and have been available since 332.Ox 4.9 . 333.Sh CAVEATS 334.Fn PKCS7_set_signed_attributes 335does not validate that 336.Fa sk 337contains the PKCS #9 content type and message digest attributes 338required by RFC 2315. 339It succeeds even when 340.Fa sk 341is empty, leaving 342.Fa si 343in a state that violates the standard. 344.Pp 345.Fn PKCS7_add0_attrib_signing_time 346does not validate 347.Fa t 348in any way. 349In particular, it may set the signing time to the future 350or to the remote past. 351.Sh BUGS 352A function to remove individual attributes from these lists 353does not appear to exist. 354A program desiring to do that might have to manually iterate the fields 355.Fa auth_attr 356and 357.Fa unauth_attr 358of 359.Fa si , 360which are both of type 361.Vt STACK_OF(X509_ATTRIBUTE) , 362using the facilities described in 363.Xr STACK_OF 3 364and 365.Xr OPENSSL_sk_new 3 . 366