cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
comp_del.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Delete Certificate Components *
4 * Copyright Peter Gutmann 1997-2008 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "cert.h"
10  #include "asn1.h"
11  #include "asn1_ext.h"
12 #else
13  #include "cert/cert.h"
14  #include "enc_dec/asn1.h"
15  #include "enc_dec/asn1_ext.h"
16 #endif /* Compiler-specific includes */
17 
18 #ifdef USE_CERTIFICATES
19 
20 /****************************************************************************
21 * *
22 * Utility Routines *
23 * *
24 ****************************************************************************/
25 
26 /* Find the head of a list of attributes for per-entry attributes, i.e. ones
27  for an individual entry in an object like a CRL rather than for the CRL
28  as a whole */
29 
31 static ATTRIBUTE_PTR **getEntryAttributeListHead( const CERT_INFO *certInfoPtr )
32  {
33  assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
34 
35  switch( certInfoPtr->type )
36  {
37 #ifdef USE_CERTVAL
40  return( &certInfoPtr->cCertVal->currentValidity->attributes );
41 #endif /* USE_CERTVAL */
42 
43 #ifdef USE_CERTREV
44  case CRYPT_CERTTYPE_CRL:
47  return( &certInfoPtr->cCertRev->currentRevocation->attributes );
48 #endif /* USE_CERTREV */
49 
50  default:
52  }
53 
55  }
56 
57 /****************************************************************************
58 * *
59 * Delete a Certificate Component *
60 * *
61 ****************************************************************************/
62 
63 /* Delete a certificate attribute */
64 
66 static int deleteCertAttribute( INOUT CERT_INFO *certInfoPtr,
67  IN_ATTRIBUTE \
69  {
70  ATTRIBUTE_PTR **attributeListHeadPtrPtr;
72  const BOOLEAN isRevocationEntry = \
73  isRevocationEntryComponent( certInfoType ) ? TRUE : FALSE;
74  int status;
75 
76  assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
77 
78  REQUIRES( isAttribute( certInfoType ) || \
79  isInternalAttribute( certInfoType ) );
80 
81  /* Try and find this attribute in the attribute list */
82  attributePtr = findAttributeComponent( certInfoPtr, certInfoType );
83  if( attributePtr == NULL )
84  return( CRYPT_ERROR_NOTFOUND );
85 
86  /* If this is a non-present field with a default value in a present
87  attribute (so that its value can be read but the field itself isn't
88  really there) there isn't any terribly satisfactory return code to
89  indicate this. Returning CRYPT_OK is wrong because the caller can
90  keep deleting the same field over and over, and returning
91  CRYPT_ERROR_NOTFOUND is wrong because the caller may have added the
92  attribute at an earlier date but it was never written because it had
93  the default value so that to the caller it appears that the field
94  they added has been lost. The least unexpected action is probably to
95  return CRYPT_OK */
96  if( checkAttributeProperty( attributePtr,
98  return( CRYPT_OK );
99 
100  /* If this is a complete attribute (e.g. CRYPT_CERTINFO_SUBJECTINFOACCESS
101  rather than one of its fields like
102  CRYPT_CERTINFO_SUBJECTINFO_CAREPOSITORY), delete the entire attribute */
103  if( checkAttributeProperty( attributePtr,
105  {
106  ATTRIBUTE_PTR *fieldAttributePtr;
107 
108  /* If the certificate has a fleur de lis make sure that it can't be
109  scraped off */
110  fieldAttributePtr = findAttribute( certInfoPtr->attributes,
111  certInfoType, TRUE );
112  if( fieldAttributePtr != NULL && \
113  checkAttributeProperty( fieldAttributePtr,
115  return( CRYPT_ERROR_PERMISSION );
116 
117  /* This is an ID for an entire (constructed) attribute, delete the
118  attribute */
119  if( isRevocationEntry )
120  attributeListHeadPtrPtr = getEntryAttributeListHead( certInfoPtr );
121  else
122  attributeListHeadPtrPtr = &certInfoPtr->attributes;
123  return( deleteCompleteAttribute( attributeListHeadPtrPtr,
124  &certInfoPtr->attributeCursor, certInfoType,
125  certInfoPtr->currentSelection.dnPtr ) );
126  }
127 
128  /* If the certificate has a fleur de lis make sure that it can't be
129  scraped off */
130  if( checkAttributeProperty( attributePtr, ATTRIBUTE_PROPERTY_LOCKED ) )
131  return( CRYPT_ERROR_PERMISSION );
132 
133  /* It's a single field, delete that */
134  if( isRevocationEntry )
135  attributeListHeadPtrPtr = getEntryAttributeListHead( certInfoPtr );
136  else
137  attributeListHeadPtrPtr = &certInfoPtr->attributes;
138  status = deleteAttributeField( attributeListHeadPtrPtr,
139  &certInfoPtr->attributeCursor, attributePtr,
140  certInfoPtr->currentSelection.dnPtr );
141 
142  /* If we've deleted the attribute containing the currently selected DN,
143  deselect it */
144  if( status == OK_SPECIAL )
145  {
146  certInfoPtr->currentSelection.dnPtr = NULL;
147  status = CRYPT_OK;
148  }
149 
150  return( status );
151  }
152 
153 /* Delete a certificate component */
154 
156 int deleteCertComponent( INOUT CERT_INFO *certInfoPtr,
157  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType )
158  {
159  int status;
160 
161  assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
162 
163  REQUIRES( isAttribute( certInfoType ) || \
164  isInternalAttribute( certInfoType ) );
165 
166  /* If it's a GeneralName or DN component, delete it. These are
167  special-case attribute values so they have to come before the
168  general attribute-handling code */
169  if( isGeneralNameSelectionComponent( certInfoType ) )
170  {
171  /* Check whether this GeneralName is present */
172  status = selectGeneralName( certInfoPtr, certInfoType,
173  MUST_BE_PRESENT );
174  if( cryptStatusError( status ) )
175  return( status );
176 
177  /* Delete each field in the GeneralName */
178  if( deleteCompositeAttributeField( &certInfoPtr->attributes,
179  &certInfoPtr->attributeCursor, certInfoPtr->attributeCursor,
180  certInfoPtr->currentSelection.dnPtr ) == OK_SPECIAL )
181  {
182  /* We've deleted the attribute containing the currently selected
183  DN, deselect it */
184  certInfoPtr->currentSelection.dnPtr = NULL;
185  }
186 
187  return( CRYPT_OK );
188  }
189  if( isGeneralNameComponent( certInfoType ) )
190  {
191  SELECTION_STATE selectionState;
192  ATTRIBUTE_PTR *attributePtr = DUMMY_INIT_PTR;
193 
194  /* Find the requested GeneralName component. Since
195  selectGeneralNameComponent() changes the current selection within
196  the GeneralName, we save the selection state around the call */
197  saveSelectionState( selectionState, certInfoPtr );
198  status = selectGeneralNameComponent( certInfoPtr, certInfoType );
199  if( cryptStatusOK( status ) )
200  attributePtr = certInfoPtr->attributeCursor;
201  restoreSelectionState( selectionState, certInfoPtr );
202  if( cryptStatusError( status ))
203  return( status );
204  ENSURES( attributePtr != NULL );
205 
206  /* Delete the field within the GeneralName */
207  if( deleteAttributeField( &certInfoPtr->attributes,
208  &certInfoPtr->attributeCursor, attributePtr,
209  certInfoPtr->currentSelection.dnPtr ) == OK_SPECIAL )
210  {
211  /* We've deleted the attribute containing the currently selected
212  DN, deselect it */
213  certInfoPtr->currentSelection.dnPtr = NULL;
214  }
215  return( CRYPT_OK );
216  }
217  if( isDNComponent( certInfoType ) )
218  {
219  status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
220  MUST_BE_PRESENT );
221  if( cryptStatusOK( status ) )
222  status = deleteDNComponent( certInfoPtr->currentSelection.dnPtr,
223  certInfoType, NULL, 0 );
224  return( status );
225  }
226 
227  /* If it's standard certificate or CMS attribute, delete it */
228  if( ( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
229  certInfoType <= CRYPT_CERTINFO_LAST_EXTENSION ) || \
230  ( certInfoType >= CRYPT_CERTINFO_FIRST_CMS && \
231  certInfoType <= CRYPT_CERTINFO_LAST_CMS ) )
232  return( deleteCertAttribute( certInfoPtr, certInfoType ) );
233 
234  /* If it's anything else, handle it specially */
235  switch( certInfoType )
236  {
238  if( !( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) )
239  return( CRYPT_ERROR_NOTFOUND );
240  certInfoPtr->flags &= ~CERT_FLAG_SELFSIGNED;
241  return( CRYPT_OK );
242 
247  if( certInfoPtr->attributeCursor == NULL )
248  return( CRYPT_ERROR_NOTFOUND );
249  if( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP )
250  {
251  status = deleteAttribute( &certInfoPtr->attributes,
252  &certInfoPtr->attributeCursor,
253  certInfoPtr->attributeCursor,
254  certInfoPtr->currentSelection.dnPtr );
255  }
256  else
257  {
258  /* The current component and field are essentially the
259  same thing since a component is one of a set of
260  entries in a multivalued field, thus they're handled
261  identically */
262  status = deleteAttributeField( &certInfoPtr->attributes,
263  &certInfoPtr->attributeCursor,
264  certInfoPtr->attributeCursor,
265  certInfoPtr->currentSelection.dnPtr );
266  }
267  if( status == OK_SPECIAL )
268  {
269  /* We've deleted the attribute containing the currently
270  selected DN, deselect it */
271  certInfoPtr->currentSelection.dnPtr = NULL;
272  }
273  return( CRYPT_OK );
274 
276  if( certInfoPtr->cCertCert->trustedUsage == CRYPT_ERROR )
277  return( CRYPT_ERROR_NOTFOUND );
278  certInfoPtr->cCertCert->trustedUsage = CRYPT_ERROR;
279  return( CRYPT_OK );
280 
282  return( krnlSendMessage( certInfoPtr->ownerHandle,
284  &certInfoPtr->objectHandle,
286 
289  if( certInfoPtr->startTime <= 0 )
290  return( CRYPT_ERROR_NOTFOUND );
291  certInfoPtr->startTime = 0;
292  return( CRYPT_OK );
293 
296  if( certInfoPtr->endTime <= 0 )
297  return( CRYPT_ERROR_NOTFOUND );
298  certInfoPtr->endTime = 0;
299  return( CRYPT_OK );
300 
302  if( certInfoPtr->currentSelection.dnPtr == &certInfoPtr->subjectName )
303  {
304  /* This is the currently selected DN, deselect it before
305  deleting it */
306  certInfoPtr->currentSelection.dnPtr = NULL;
307  }
308  deleteDN( &certInfoPtr->subjectName );
309  return( CRYPT_OK );
310 
311 #ifdef USE_CERTREV
313  {
314  time_t *revocationTimePtr = ( time_t * ) \
315  getRevocationTimePtr( certInfoPtr );
316 
317  if( revocationTimePtr == NULL )
318  return( CRYPT_ERROR_NOTFOUND );
319  *revocationTimePtr = 0;
320  return( CRYPT_OK );
321  }
322 #endif /* USE_CERTREV */
323  }
324 
325  retIntError();
326  }
327 #endif /* USE_CERTIFICATES */