188 public KeySelectorResult getKeySelectorResult() { |
192 public KeySelectorResult getKeySelectorResult() { |
189 return ksr; |
193 return ksr; |
190 } |
194 } |
191 |
195 |
192 public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) |
196 public void marshal(Node parent, String dsPrefix, DOMCryptoContext context) |
193 throws MarshalException { |
197 throws MarshalException |
|
198 { |
194 marshal(parent, null, dsPrefix, context); |
199 marshal(parent, null, dsPrefix, context); |
195 } |
200 } |
196 |
201 |
197 public void marshal(Node parent, Node nextSibling, String dsPrefix, |
202 public void marshal(Node parent, Node nextSibling, String dsPrefix, |
198 DOMCryptoContext context) throws MarshalException { |
203 DOMCryptoContext context) |
|
204 throws MarshalException |
|
205 { |
199 ownerDoc = DOMUtils.getOwnerDocument(parent); |
206 ownerDoc = DOMUtils.getOwnerDocument(parent); |
200 |
207 sigElem = DOMUtils.createElement(ownerDoc, "Signature", |
201 sigElem = DOMUtils.createElement |
208 XMLSignature.XMLNS, dsPrefix); |
202 (ownerDoc, "Signature", XMLSignature.XMLNS, dsPrefix); |
|
203 |
209 |
204 // append xmlns attribute |
210 // append xmlns attribute |
205 if (dsPrefix == null || dsPrefix.length() == 0) { |
211 if (dsPrefix == null || dsPrefix.length() == 0) { |
206 sigElem.setAttributeNS |
212 sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", |
207 ("http://www.w3.org/2000/xmlns/", "xmlns", XMLSignature.XMLNS); |
213 XMLSignature.XMLNS); |
208 } else { |
214 } else { |
209 sigElem.setAttributeNS |
215 sigElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + |
210 ("http://www.w3.org/2000/xmlns/", "xmlns:" + dsPrefix, |
216 dsPrefix, XMLSignature.XMLNS); |
211 XMLSignature.XMLNS); |
|
212 } |
217 } |
213 |
218 |
214 // create and append SignedInfo element |
219 // create and append SignedInfo element |
215 ((DOMSignedInfo) si).marshal(sigElem, dsPrefix, context); |
220 ((DOMSignedInfo)si).marshal(sigElem, dsPrefix, context); |
216 |
221 |
217 // create and append SignatureValue element |
222 // create and append SignatureValue element |
218 ((DOMSignatureValue) sv).marshal(sigElem, dsPrefix, context); |
223 ((DOMSignatureValue)sv).marshal(sigElem, dsPrefix, context); |
219 |
224 |
220 // create and append KeyInfo element if necessary |
225 // create and append KeyInfo element if necessary |
221 if (ki != null) { |
226 if (ki != null) { |
222 ((DOMKeyInfo) ki).marshal(sigElem, null, dsPrefix, context); |
227 ((DOMKeyInfo)ki).marshal(sigElem, null, dsPrefix, context); |
223 } |
228 } |
224 |
229 |
225 // create and append Object elements if necessary |
230 // create and append Object elements if necessary |
226 for (int i = 0, size = objects.size(); i < size; i++) { |
231 for (int i = 0, size = objects.size(); i < size; i++) { |
227 ((DOMXMLObject) objects.get(i)).marshal(sigElem, dsPrefix, context); |
232 ((DOMXMLObject)objects.get(i)).marshal(sigElem, dsPrefix, context); |
228 } |
233 } |
229 |
234 |
230 // append Id attribute |
235 // append Id attribute |
231 DOMUtils.setAttributeID(sigElem, "Id", id); |
236 DOMUtils.setAttributeID(sigElem, "Id", id); |
232 |
237 |
233 parent.insertBefore(sigElem, nextSibling); |
238 parent.insertBefore(sigElem, nextSibling); |
234 } |
239 } |
235 |
240 |
236 public boolean validate(XMLValidateContext vc) |
241 public boolean validate(XMLValidateContext vc) |
237 throws XMLSignatureException { |
242 throws XMLSignatureException |
238 |
243 { |
239 if (vc == null) { |
244 if (vc == null) { |
240 throw new NullPointerException("validateContext is null"); |
245 throw new NullPointerException("validateContext is null"); |
241 } |
246 } |
242 |
247 |
243 if (!(vc instanceof DOMValidateContext)) { |
248 if (!(vc instanceof DOMValidateContext)) { |
256 validated = true; |
261 validated = true; |
257 return validationStatus; |
262 return validationStatus; |
258 } |
263 } |
259 |
264 |
260 // validate all References |
265 // validate all References |
261 List refs = this.si.getReferences(); |
266 @SuppressWarnings("unchecked") |
|
267 List<Reference> refs = this.si.getReferences(); |
262 boolean validateRefs = true; |
268 boolean validateRefs = true; |
263 for (int i = 0, size = refs.size(); validateRefs && i < size; i++) { |
269 for (int i = 0, size = refs.size(); validateRefs && i < size; i++) { |
264 Reference ref = (Reference) refs.get(i); |
270 Reference ref = refs.get(i); |
265 boolean refValid = ref.validate(vc); |
271 boolean refValid = ref.validate(vc); |
266 if (log.isLoggable(Level.FINE)) { |
272 if (log.isLoggable(java.util.logging.Level.FINE)) { |
267 log.log(Level.FINE, "Reference[" + ref.getURI() + "] is valid: " |
273 log.log(java.util.logging.Level.FINE, "Reference[" + ref.getURI() + "] is valid: " + refValid); |
268 + refValid); |
|
269 } |
274 } |
270 validateRefs &= refValid; |
275 validateRefs &= refValid; |
271 } |
276 } |
272 if (!validateRefs) { |
277 if (!validateRefs) { |
273 if (log.isLoggable(Level.FINE)) { |
278 if (log.isLoggable(java.util.logging.Level.FINE)) { |
274 log.log(Level.FINE, "Couldn't validate the References"); |
279 log.log(java.util.logging.Level.FINE, "Couldn't validate the References"); |
275 } |
280 } |
276 validationStatus = false; |
281 validationStatus = false; |
277 validated = true; |
282 validated = true; |
278 return validationStatus; |
283 return validationStatus; |
279 } |
284 } |
280 |
285 |
281 // validate Manifests, if property set |
286 // validate Manifests, if property set |
282 boolean validateMans = true; |
287 boolean validateMans = true; |
283 if (Boolean.TRUE.equals(vc.getProperty |
288 if (Boolean.TRUE.equals(vc.getProperty |
284 ("org.jcp.xml.dsig.validateManifests"))) { |
289 ("org.jcp.xml.dsig.validateManifests"))) |
285 |
290 { |
286 for (int i=0, size=objects.size(); validateMans && i < size; i++) { |
291 for (int i=0, size=objects.size(); validateMans && i < size; i++) { |
287 XMLObject xo = (XMLObject) objects.get(i); |
292 XMLObject xo = objects.get(i); |
288 List content = xo.getContent(); |
293 @SuppressWarnings("unchecked") |
|
294 List<XMLStructure> content = xo.getContent(); |
289 int csize = content.size(); |
295 int csize = content.size(); |
290 for (int j = 0; validateMans && j < csize; j++) { |
296 for (int j = 0; validateMans && j < csize; j++) { |
291 XMLStructure xs = (XMLStructure) content.get(j); |
297 XMLStructure xs = content.get(j); |
292 if (xs instanceof Manifest) { |
298 if (xs instanceof Manifest) { |
293 if (log.isLoggable(Level.FINE)) { |
299 if (log.isLoggable(java.util.logging.Level.FINE)) { |
294 log.log(Level.FINE, "validating manifest"); |
300 log.log(java.util.logging.Level.FINE, "validating manifest"); |
295 } |
301 } |
296 Manifest man = (Manifest) xs; |
302 Manifest man = (Manifest)xs; |
297 List manRefs = man.getReferences(); |
303 @SuppressWarnings("unchecked") |
|
304 List<Reference> manRefs = man.getReferences(); |
298 int rsize = manRefs.size(); |
305 int rsize = manRefs.size(); |
299 for (int k = 0; validateMans && k < rsize; k++) { |
306 for (int k = 0; validateMans && k < rsize; k++) { |
300 Reference ref = (Reference) manRefs.get(k); |
307 Reference ref = manRefs.get(k); |
301 boolean refValid = ref.validate(vc); |
308 boolean refValid = ref.validate(vc); |
302 if (log.isLoggable(Level.FINE)) { |
309 if (log.isLoggable(java.util.logging.Level.FINE)) { |
303 log.log(Level.FINE, "Manifest ref[" |
310 log.log(java.util.logging.Level.FINE, |
304 + ref.getURI() + "] is valid: " + refValid); |
311 "Manifest ref[" + ref.getURI() + "] is valid: " + refValid |
|
312 ); |
305 } |
313 } |
306 validateMans &= refValid; |
314 validateMans &= refValid; |
307 } |
315 } |
308 } |
316 } |
309 } |
317 } |
314 validated = true; |
322 validated = true; |
315 return validationStatus; |
323 return validationStatus; |
316 } |
324 } |
317 |
325 |
318 public void sign(XMLSignContext signContext) |
326 public void sign(XMLSignContext signContext) |
319 throws MarshalException, XMLSignatureException { |
327 throws MarshalException, XMLSignatureException |
|
328 { |
320 if (signContext == null) { |
329 if (signContext == null) { |
321 throw new NullPointerException("signContext cannot be null"); |
330 throw new NullPointerException("signContext cannot be null"); |
322 } |
331 } |
323 DOMSignContext context = (DOMSignContext) signContext; |
332 DOMSignContext context = (DOMSignContext)signContext; |
324 if (context != null) { |
333 marshal(context.getParent(), context.getNextSibling(), |
325 marshal(context.getParent(), context.getNextSibling(), |
|
326 DOMUtils.getSignaturePrefix(context), context); |
334 DOMUtils.getSignaturePrefix(context), context); |
327 } |
|
328 |
335 |
329 // generate references and signature value |
336 // generate references and signature value |
330 List allReferences = new ArrayList(); |
337 List<Reference> allReferences = new ArrayList<Reference>(); |
331 |
338 |
332 // traverse the Signature and register all objects with IDs that |
339 // traverse the Signature and register all objects with IDs that |
333 // may contain References |
340 // may contain References |
334 signatureIdMap = new HashMap(); |
341 signatureIdMap = new HashMap<String, XMLStructure>(); |
335 signatureIdMap.put(id, this); |
342 signatureIdMap.put(id, this); |
336 signatureIdMap.put(si.getId(), si); |
343 signatureIdMap.put(si.getId(), si); |
337 List refs = si.getReferences(); |
344 @SuppressWarnings("unchecked") |
338 for (int i = 0, size = refs.size(); i < size; i++) { |
345 List<Reference> refs = si.getReferences(); |
339 Reference ref = (Reference) refs.get(i); |
346 for (Reference ref : refs) { |
340 signatureIdMap.put(ref.getId(), ref); |
347 signatureIdMap.put(ref.getId(), ref); |
341 } |
348 } |
342 for (int i = 0, size = objects.size(); i < size; i++) { |
349 for (XMLObject obj : objects) { |
343 XMLObject obj = (XMLObject) objects.get(i); |
|
344 signatureIdMap.put(obj.getId(), obj); |
350 signatureIdMap.put(obj.getId(), obj); |
345 List content = obj.getContent(); |
351 @SuppressWarnings("unchecked") |
346 for (int j = 0, csize = content.size(); j < csize; j++) { |
352 List<XMLStructure> content = obj.getContent(); |
347 XMLStructure xs = (XMLStructure) content.get(j); |
353 for (XMLStructure xs : content) { |
348 if (xs instanceof Manifest) { |
354 if (xs instanceof Manifest) { |
349 Manifest man = (Manifest) xs; |
355 Manifest man = (Manifest)xs; |
350 signatureIdMap.put(man.getId(), man); |
356 signatureIdMap.put(man.getId(), man); |
351 List manRefs = man.getReferences(); |
357 @SuppressWarnings("unchecked") |
352 for (int k = 0, msize = manRefs.size(); k < msize; k++) { |
358 List<Reference> manRefs = man.getReferences(); |
353 Reference ref = (Reference) manRefs.get(k); |
359 for (Reference ref : manRefs) { |
354 allReferences.add(ref); |
360 allReferences.add(ref); |
355 signatureIdMap.put(ref.getId(), ref); |
361 signatureIdMap.put(ref.getId(), ref); |
356 } |
362 } |
357 } |
363 } |
358 } |
364 } |
359 } |
365 } |
360 // always add SignedInfo references after Manifest references so |
366 // always add SignedInfo references after Manifest references so |
361 // that Manifest reference are digested first |
367 // that Manifest reference are digested first |
362 allReferences.addAll(si.getReferences()); |
368 allReferences.addAll(refs); |
363 |
369 |
364 // generate/digest each reference |
370 // generate/digest each reference |
365 for (int i = 0, size = allReferences.size(); i < size; i++) { |
371 for (Reference ref : allReferences) { |
366 DOMReference ref = (DOMReference) allReferences.get(i); |
372 digestReference((DOMReference)ref, signContext); |
367 digestReference(ref, signContext); |
|
368 } |
373 } |
369 |
374 |
370 // do final sweep to digest any references that were skipped or missed |
375 // do final sweep to digest any references that were skipped or missed |
371 for (int i = 0, size = allReferences.size(); i < size; i++) { |
376 for (Reference ref : allReferences) { |
372 DOMReference ref = (DOMReference) allReferences.get(i); |
377 if (((DOMReference)ref).isDigested()) { |
373 if (ref.isDigested()) { |
|
374 continue; |
378 continue; |
375 } |
379 } |
376 ref.digest(signContext); |
380 ((DOMReference)ref).digest(signContext); |
377 } |
381 } |
378 |
382 |
379 Key signingKey = null; |
383 Key signingKey = null; |
380 KeySelectorResult ksr = null; |
384 KeySelectorResult ksr = null; |
381 try { |
385 try { |
382 ksr = signContext.getKeySelector().select |
386 ksr = signContext.getKeySelector().select(ki, |
383 (ki, KeySelector.Purpose.SIGN, |
387 KeySelector.Purpose.SIGN, |
384 si.getSignatureMethod(), signContext); |
388 si.getSignatureMethod(), |
|
389 signContext); |
385 signingKey = ksr.getKey(); |
390 signingKey = ksr.getKey(); |
386 if (signingKey == null) { |
391 if (signingKey == null) { |
387 throw new XMLSignatureException("the keySelector did not " + |
392 throw new XMLSignatureException("the keySelector did not " + |
388 "find a signing key"); |
393 "find a signing key"); |
389 } |
394 } |
390 } catch (KeySelectorException kse) { |
395 } catch (KeySelectorException kse) { |
391 throw new XMLSignatureException("cannot find signing key", kse); |
396 throw new XMLSignatureException("cannot find signing key", kse); |
392 } |
397 } |
393 |
398 |
394 // calculate signature value |
399 // calculate signature value |
395 byte[] val = null; |
|
396 try { |
400 try { |
397 val = ((DOMSignatureMethod) si.getSignatureMethod()).sign |
401 byte[] val = ((AbstractDOMSignatureMethod) |
398 (signingKey, (DOMSignedInfo) si, signContext); |
402 si.getSignatureMethod()).sign(signingKey, si, signContext); |
|
403 ((DOMSignatureValue)sv).setValue(val); |
399 } catch (InvalidKeyException ike) { |
404 } catch (InvalidKeyException ike) { |
400 throw new XMLSignatureException(ike); |
405 throw new XMLSignatureException(ike); |
401 } |
406 } |
402 |
407 |
403 if (log.isLoggable(Level.FINE)) { |
|
404 log.log(Level.FINE, "SignatureValue = " + val); |
|
405 } |
|
406 ((DOMSignatureValue) sv).setValue(val); |
|
407 |
|
408 this.localSigElem = sigElem; |
408 this.localSigElem = sigElem; |
409 this.ksr = ksr; |
409 this.ksr = ksr; |
410 } |
410 } |
411 |
411 |
|
412 @Override |
412 public boolean equals(Object o) { |
413 public boolean equals(Object o) { |
413 if (this == o) { |
414 if (this == o) { |
414 return true; |
415 return true; |
415 } |
416 } |
416 |
417 |
417 if (!(o instanceof XMLSignature)) { |
418 if (!(o instanceof XMLSignature)) { |
418 return false; |
419 return false; |
419 } |
420 } |
420 XMLSignature osig = (XMLSignature) o; |
421 XMLSignature osig = (XMLSignature)o; |
421 |
422 |
422 boolean idEqual = |
423 boolean idEqual = |
423 (id == null ? osig.getId() == null : id.equals(osig.getId())); |
424 (id == null ? osig.getId() == null : id.equals(osig.getId())); |
424 boolean keyInfoEqual = |
425 boolean keyInfoEqual = |
425 (ki == null ? osig.getKeyInfo() == null : |
426 (ki == null ? osig.getKeyInfo() == null |
426 ki.equals(osig.getKeyInfo())); |
427 : ki.equals(osig.getKeyInfo())); |
427 |
428 |
428 return (idEqual && keyInfoEqual && |
429 return (idEqual && keyInfoEqual && |
429 sv.equals(osig.getSignatureValue()) && |
430 sv.equals(osig.getSignatureValue()) && |
430 si.equals(osig.getSignedInfo()) && |
431 si.equals(osig.getSignedInfo()) && |
431 objects.equals(osig.getObjects())); |
432 objects.equals(osig.getObjects())); |
|
433 } |
|
434 |
|
435 @Override |
|
436 public int hashCode() { |
|
437 int result = 17; |
|
438 if (id != null) { |
|
439 result = 31 * result + id.hashCode(); |
|
440 } |
|
441 if (ki != null) { |
|
442 result = 31 * result + ki.hashCode(); |
|
443 } |
|
444 result = 31 * result + sv.hashCode(); |
|
445 result = 31 * result + si.hashCode(); |
|
446 result = 31 * result + objects.hashCode(); |
|
447 |
|
448 return result; |
432 } |
449 } |
433 |
450 |
434 private void digestReference(DOMReference ref, XMLSignContext signContext) |
451 private void digestReference(DOMReference ref, XMLSignContext signContext) |
435 throws XMLSignatureException { |
452 throws XMLSignatureException |
|
453 { |
436 if (ref.isDigested()) { |
454 if (ref.isDigested()) { |
437 return; |
455 return; |
438 } |
456 } |
439 // check dependencies |
457 // check dependencies |
440 String uri = ref.getURI(); |
458 String uri = ref.getURI(); |
441 if (Utils.sameDocumentURI(uri)) { |
459 if (Utils.sameDocumentURI(uri)) { |
442 String id = Utils.parseIdFromSameDocumentURI(uri); |
460 String id = Utils.parseIdFromSameDocumentURI(uri); |
443 if (id != null && signatureIdMap.containsKey(id)) { |
461 if (id != null && signatureIdMap.containsKey(id)) { |
444 Object obj = signatureIdMap.get(id); |
462 XMLStructure xs = signatureIdMap.get(id); |
445 if (obj instanceof DOMReference) { |
463 if (xs instanceof DOMReference) { |
446 digestReference((DOMReference) obj, signContext); |
464 digestReference((DOMReference)xs, signContext); |
447 } else if (obj instanceof Manifest) { |
465 } else if (xs instanceof Manifest) { |
448 Manifest man = (Manifest) obj; |
466 Manifest man = (Manifest)xs; |
449 List manRefs = man.getReferences(); |
467 List manRefs = man.getReferences(); |
450 for (int i = 0, size = manRefs.size(); i < size; i++) { |
468 for (int i = 0, size = manRefs.size(); i < size; i++) { |
451 digestReference |
469 digestReference((DOMReference)manRefs.get(i), |
452 ((DOMReference) manRefs.get(i), signContext); |
470 signContext); |
453 } |
471 } |
454 } |
472 } |
455 } |
473 } |
456 // if uri="" and there are XPath Transforms, there may be |
474 // if uri="" and there are XPath Transforms, there may be |
457 // reference dependencies in the XPath Transform - so be on |
475 // reference dependencies in the XPath Transform - so be on |
458 // the safe side, and skip and do at end in the final sweep |
476 // the safe side, and skip and do at end in the final sweep |
459 if (uri.length() == 0) { |
477 if (uri.length() == 0) { |
460 List transforms = ref.getTransforms(); |
478 @SuppressWarnings("unchecked") |
461 for (int i = 0, size = transforms.size(); i < size; i++) { |
479 List<Transform> transforms = ref.getTransforms(); |
462 Transform transform = (Transform) transforms.get(i); |
480 for (Transform transform : transforms) { |
463 String transformAlg = transform.getAlgorithm(); |
481 String transformAlg = transform.getAlgorithm(); |
464 if (transformAlg.equals(Transform.XPATH) || |
482 if (transformAlg.equals(Transform.XPATH) || |
465 transformAlg.equals(Transform.XPATH2)) { |
483 transformAlg.equals(Transform.XPATH2)) { |
466 return; |
484 return; |
467 } |
485 } |
529 try { |
549 try { |
530 ksResult = validateContext.getKeySelector().select |
550 ksResult = validateContext.getKeySelector().select |
531 (ki, KeySelector.Purpose.VERIFY, sm, validateContext); |
551 (ki, KeySelector.Purpose.VERIFY, sm, validateContext); |
532 validationKey = ksResult.getKey(); |
552 validationKey = ksResult.getKey(); |
533 if (validationKey == null) { |
553 if (validationKey == null) { |
534 throw new XMLSignatureException("the keyselector did " + |
554 throw new XMLSignatureException("the keyselector did not " + |
535 "not find a validation key"); |
555 "find a validation key"); |
536 } |
556 } |
537 } catch (KeySelectorException kse) { |
557 } catch (KeySelectorException kse) { |
538 throw new XMLSignatureException("cannot find validation " + |
558 throw new XMLSignatureException("cannot find validation " + |
539 "key", kse); |
559 "key", kse); |
540 } |
560 } |
541 |
561 |
542 // canonicalize SignedInfo and verify signature |
562 // canonicalize SignedInfo and verify signature |
543 try { |
563 try { |
544 validationStatus = ((DOMSignatureMethod) sm).verify |
564 validationStatus = ((AbstractDOMSignatureMethod)sm).verify |
545 (validationKey, (DOMSignedInfo) si, value, validateContext); |
565 (validationKey, si, value, validateContext); |
546 } catch (Exception e) { |
566 } catch (Exception e) { |
547 throw new XMLSignatureException(e); |
567 throw new XMLSignatureException(e); |
548 } |
568 } |
549 |
569 |
550 validated = true; |
570 validated = true; |
551 ksr = ksResult; |
571 ksr = ksResult; |
552 return validationStatus; |
572 return validationStatus; |
553 } |
573 } |
554 |
574 |
|
575 @Override |
555 public boolean equals(Object o) { |
576 public boolean equals(Object o) { |
556 if (this == o) { |
577 if (this == o) { |
557 return true; |
578 return true; |
558 } |
579 } |
559 |
580 |
560 if (!(o instanceof SignatureValue)) { |
581 if (!(o instanceof SignatureValue)) { |
561 return false; |
582 return false; |
562 } |
583 } |
563 SignatureValue osv = (SignatureValue) o; |
584 SignatureValue osv = (SignatureValue)o; |
564 |
585 |
565 boolean idEqual = |
586 boolean idEqual = |
566 (id == null ? osv.getId() == null : id.equals(osv.getId())); |
587 (id == null ? osv.getId() == null : id.equals(osv.getId())); |
567 |
588 |
568 //XXX compare signature values? |
589 //XXX compare signature values? |
569 return idEqual; |
590 return idEqual; |
570 } |
591 } |
571 |
592 |
|
593 @Override |
|
594 public int hashCode() { |
|
595 int result = 17; |
|
596 if (id != null) { |
|
597 result = 31 * result + id.hashCode(); |
|
598 } |
|
599 |
|
600 return result; |
|
601 } |
|
602 |
572 public void marshal(Node parent, String dsPrefix, |
603 public void marshal(Node parent, String dsPrefix, |
573 DOMCryptoContext context) throws MarshalException { |
604 DOMCryptoContext context) |
574 |
605 throws MarshalException |
|
606 { |
575 // create SignatureValue element |
607 // create SignatureValue element |
576 sigValueElem = DOMUtils.createElement |
608 sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue", |
577 (ownerDoc, "SignatureValue", XMLSignature.XMLNS, dsPrefix); |
609 XMLSignature.XMLNS, dsPrefix); |
578 if (valueBase64 != null) { |
610 if (valueBase64 != null) { |
579 sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64)); |
611 sigValueElem.appendChild(ownerDoc.createTextNode(valueBase64)); |
580 } |
612 } |
581 |
613 |
582 // append Id attribute, if specified |
614 // append Id attribute, if specified |