Update ooo320-m1
[ooovba.git] / xmlsecurity / source / xmlsec / nss / x509certificate_nssimpl.cxx
blob93dc1873d3aea6c26aeae2fc566d4587f519cd7a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: x509certificate_nssimpl.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
36 #include "nssrenam.h"
37 #include "nspr.h"
38 #include "nss.h"
39 #include "secder.h"
41 //MM : added by MM
42 #include "hasht.h"
43 #include "secoid.h"
44 #include "pk11func.h"
45 //MM : end
49 #include <sal/config.h>
50 #include <rtl/uuid.h>
51 #include "x509certificate_nssimpl.hxx"
53 #ifndef _CERTIFICATEEXTENSION_NSSIMPL_HXX_
54 #include "certificateextension_xmlsecimpl.hxx"
55 #endif
58 using namespace ::com::sun::star::uno ;
59 using namespace ::com::sun::star::security ;
60 using ::rtl::OUString ;
62 using ::com::sun::star::security::XCertificate ;
63 using ::com::sun::star::util::DateTime ;
65 X509Certificate_NssImpl :: X509Certificate_NssImpl() :
66 m_pCert( NULL )
70 X509Certificate_NssImpl :: ~X509Certificate_NssImpl() {
71 if( m_pCert != NULL ) {
72 CERT_DestroyCertificate( m_pCert ) ;
76 //Methods from XCertificate
77 sal_Int16 SAL_CALL X509Certificate_NssImpl :: getVersion() throw ( ::com::sun::star::uno::RuntimeException) {
78 if( m_pCert != NULL ) {
79 if( m_pCert->version.len > 0 ) {
80 return ( char )*( m_pCert->version.data ) ;
81 } else
82 return 0 ;
83 } else {
84 return -1 ;
88 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) {
89 if( m_pCert != NULL && m_pCert->serialNumber.len > 0 ) {
90 Sequence< sal_Int8 > serial( m_pCert->serialNumber.len ) ;
91 for( unsigned int i = 0 ; i < m_pCert->serialNumber.len ; i ++ )
92 serial[i] = *( m_pCert->serialNumber.data + i ) ;
94 return serial ;
95 } else {
96 return ::com::sun::star::uno::Sequence< sal_Int8 >();
100 ::rtl::OUString SAL_CALL X509Certificate_NssImpl :: getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) {
101 if( m_pCert != NULL ) {
102 return OUString(m_pCert->issuerName , PL_strlen(m_pCert->issuerName) , RTL_TEXTENCODING_UTF8) ;
103 } else {
104 return OUString() ;
108 ::rtl::OUString SAL_CALL X509Certificate_NssImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) {
109 if( m_pCert != NULL ) {
110 return OUString(m_pCert->subjectName , PL_strlen(m_pCert->subjectName) , RTL_TEXTENCODING_UTF8);
111 } else {
112 return OUString() ;
116 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_NssImpl :: getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException) {
117 if( m_pCert != NULL ) {
118 SECStatus rv ;
119 PRTime notBefore ;
120 PRExplodedTime explTime ;
121 DateTime dateTime ;
123 rv = DER_DecodeTimeChoice( &notBefore, &m_pCert->validity.notBefore ) ;
124 if( rv ) {
125 return DateTime() ;
128 //Convert the time to readable local time
129 PR_ExplodeTime( notBefore, PR_LocalTimeParameters, &explTime ) ;
131 dateTime.HundredthSeconds = explTime.tm_usec / 1000 ;
132 dateTime.Seconds = explTime.tm_sec ;
133 dateTime.Minutes = explTime.tm_min ;
134 dateTime.Hours = explTime.tm_hour ;
135 dateTime.Day = explTime.tm_mday ;
136 dateTime.Month = explTime.tm_month+1 ;
137 dateTime.Year = explTime.tm_year ;
139 return dateTime ;
140 } else {
141 return DateTime() ;
145 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_NssImpl :: getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) {
146 if( m_pCert != NULL ) {
147 SECStatus rv ;
148 PRTime notAfter ;
149 PRExplodedTime explTime ;
150 DateTime dateTime ;
152 rv = DER_DecodeTimeChoice( &notAfter, &m_pCert->validity.notAfter ) ;
153 if( rv ) {
154 return DateTime() ;
157 //Convert the time to readable local time
158 PR_ExplodeTime( notAfter, PR_LocalTimeParameters, &explTime ) ;
160 dateTime.HundredthSeconds = explTime.tm_usec / 1000 ;
161 dateTime.Seconds = explTime.tm_sec ;
162 dateTime.Minutes = explTime.tm_min ;
163 dateTime.Hours = explTime.tm_hour ;
164 dateTime.Day = explTime.tm_mday ;
165 dateTime.Month = explTime.tm_month+1 ;
166 dateTime.Year = explTime.tm_year ;
168 return dateTime ;
169 } else {
170 return DateTime() ;
174 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) {
175 if( m_pCert != NULL && m_pCert->issuerID.len > 0 ) {
176 Sequence< sal_Int8 > issuerUid( m_pCert->issuerID.len ) ;
177 for( unsigned int i = 0 ; i < m_pCert->issuerID.len ; i ++ )
178 issuerUid[i] = *( m_pCert->issuerID.data + i ) ;
180 return issuerUid ;
181 } else {
182 return ::com::sun::star::uno::Sequence< sal_Int8 >();
186 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException) {
187 if( m_pCert != NULL && m_pCert->subjectID.len > 0 ) {
188 Sequence< sal_Int8 > subjectUid( m_pCert->subjectID.len ) ;
189 for( unsigned int i = 0 ; i < m_pCert->subjectID.len ; i ++ )
190 subjectUid[i] = *( m_pCert->subjectID.data + i ) ;
192 return subjectUid ;
193 } else {
194 return ::com::sun::star::uno::Sequence< sal_Int8 >();
198 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL X509Certificate_NssImpl :: getExtensions() throw ( ::com::sun::star::uno::RuntimeException) {
199 if( m_pCert != NULL && m_pCert->extensions != NULL ) {
200 CERTCertExtension** extns ;
201 CertificateExtension_XmlSecImpl* pExtn ;
202 sal_Bool crit ;
203 int len ;
205 for( len = 0, extns = m_pCert->extensions; *extns != NULL; len ++, extns ++ ) ;
206 Sequence< Reference< XCertificateExtension > > xExtns( len ) ;
208 for( extns = m_pCert->extensions, len = 0; *extns != NULL; extns ++, len ++ ) {
209 pExtn = new CertificateExtension_XmlSecImpl() ;
210 if( (*extns)->critical.data == NULL )
211 crit = sal_False ;
212 else
213 crit = ( (*extns)->critical.data[0] == 0xFF ) ? sal_True : sal_False ;
214 pExtn->setCertExtn( (*extns)->value.data, (*extns)->value.len, (*extns)->id.data, (*extns)->id.len, crit ) ;
216 xExtns[len] = pExtn ;
219 return xExtns ;
220 } else {
221 return ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > ();
225 ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL X509Certificate_NssImpl :: findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& oid ) throw (::com::sun::star::uno::RuntimeException) {
226 if( m_pCert != NULL && m_pCert->extensions != NULL ) {
227 CertificateExtension_XmlSecImpl* pExtn ;
228 CERTCertExtension** extns ;
229 SECItem idItem ;
230 sal_Bool crit ;
232 idItem.data = ( unsigned char* )&oid[0] ;
233 idItem.len = oid.getLength() ;
235 pExtn = NULL ;
236 for( extns = m_pCert->extensions; *extns != NULL; extns ++ ) {
237 if( SECITEM_CompareItem( &idItem, &(*extns)->id ) == SECEqual ) {
238 pExtn = new CertificateExtension_XmlSecImpl() ;
239 if( (*extns)->critical.data == NULL )
240 crit = sal_False ;
241 else
242 crit = ( (*extns)->critical.data[0] == 0xFF ) ? sal_True : sal_False ;
243 pExtn->setCertExtn( (*extns)->value.data, (*extns)->value.len, (*extns)->id.data, (*extns)->id.len, crit ) ;
247 return pExtn ;
248 } else {
249 return NULL ;
254 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getEncoded() throw ( ::com::sun::star::uno::RuntimeException) {
255 if( m_pCert != NULL && m_pCert->derCert.len > 0 ) {
256 Sequence< sal_Int8 > rawCert( m_pCert->derCert.len ) ;
258 for( unsigned int i = 0 ; i < m_pCert->derCert.len ; i ++ )
259 rawCert[i] = *( m_pCert->derCert.data + i ) ;
261 return rawCert ;
262 } else {
263 return ::com::sun::star::uno::Sequence< sal_Int8 >();
267 //Helper methods
268 void X509Certificate_NssImpl :: setCert( CERTCertificate* cert ) {
269 if( m_pCert != NULL ) {
270 CERT_DestroyCertificate( m_pCert ) ;
271 m_pCert = NULL ;
274 if( cert != NULL ) {
275 m_pCert = CERT_DupCertificate( cert ) ;
279 const CERTCertificate* X509Certificate_NssImpl :: getNssCert() const {
280 if( m_pCert != NULL ) {
281 return m_pCert ;
282 } else {
283 return NULL ;
287 void X509Certificate_NssImpl :: setRawCert( Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) {
288 CERTCertificate* cert ;
289 SECItem certItem ;
291 certItem.data = ( unsigned char* )&rawCert[0] ;
292 certItem.len = rawCert.getLength() ;
294 cert = CERT_DecodeDERCertificate( &certItem, PR_TRUE, NULL ) ;
295 if( cert == NULL )
296 throw RuntimeException() ;
298 if( m_pCert != NULL ) {
299 CERT_DestroyCertificate( m_pCert ) ;
300 m_pCert = NULL ;
303 m_pCert = cert ;
306 /* XUnoTunnel */
307 sal_Int64 SAL_CALL X509Certificate_NssImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw( RuntimeException ) {
308 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
309 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
311 return 0 ;
314 /* XUnoTunnel extension */
315 const Sequence< sal_Int8>& X509Certificate_NssImpl :: getUnoTunnelId() {
316 static Sequence< sal_Int8 >* pSeq = 0 ;
317 if( !pSeq ) {
318 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
319 if( !pSeq ) {
320 static Sequence< sal_Int8> aSeq( 16 ) ;
321 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
322 pSeq = &aSeq ;
325 return *pSeq ;
328 /* XUnoTunnel extension */
329 X509Certificate_NssImpl* X509Certificate_NssImpl :: getImplementation( const Reference< XInterface > xObj ) {
330 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
331 if( xUT.is() ) {
332 return reinterpret_cast<X509Certificate_NssImpl*>(
333 sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( getUnoTunnelId() )));
334 } else
335 return NULL ;
338 // MM : added by MM
339 ::rtl::OUString getAlgorithmDescription(SECAlgorithmID *aid)
341 SECOidTag tag;
342 tag = SECOID_GetAlgorithmTag(aid);
344 const char *pDesc = SECOID_FindOIDTagDescription(tag);
346 return rtl::OUString::createFromAscii( pDesc ) ;
349 ::com::sun::star::uno::Sequence< sal_Int8 > getThumbprint(CERTCertificate *pCert, SECOidTag id)
351 if( pCert != NULL )
353 unsigned char fingerprint[20];
354 //char *fpStr = NULL;
355 SECItem fpItem;
356 int length = ((id == SEC_OID_MD5)?MD5_LENGTH:SHA1_LENGTH);
358 memset(fingerprint, 0, sizeof fingerprint);
359 PK11_HashBuf(id, fingerprint, pCert->derCert.data, pCert->derCert.len);
360 fpItem.data = fingerprint;
361 fpItem.len = length;
362 //fpStr = CERT_Hexify(&fpItem, 1);
364 Sequence< sal_Int8 > thumbprint( length ) ;
365 for( int i = 0 ; i < length ; i ++ )
367 thumbprint[i] = fingerprint[i];
370 //PORT_Free(fpStr);
371 return thumbprint;
373 else
375 return ::com::sun::star::uno::Sequence< sal_Int8 >();
379 ::rtl::OUString SAL_CALL X509Certificate_NssImpl::getSubjectPublicKeyAlgorithm()
380 throw ( ::com::sun::star::uno::RuntimeException)
382 if( m_pCert != NULL )
384 return getAlgorithmDescription(&(m_pCert->subjectPublicKeyInfo.algorithm));
386 else
388 return OUString() ;
392 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getSubjectPublicKeyValue()
393 throw ( ::com::sun::star::uno::RuntimeException)
395 if( m_pCert != NULL )
397 SECItem spk = m_pCert->subjectPublicKeyInfo.subjectPublicKey;
398 DER_ConvertBitString(&spk);
400 if ( spk.len>0)
402 Sequence< sal_Int8 > key( spk.len ) ;
403 for( unsigned int i = 0 ; i < spk.len ; i ++ )
405 key[i] = *( spk.data + i ) ;
408 return key ;
412 return ::com::sun::star::uno::Sequence< sal_Int8 >();
415 ::rtl::OUString SAL_CALL X509Certificate_NssImpl::getSignatureAlgorithm()
416 throw ( ::com::sun::star::uno::RuntimeException)
418 if( m_pCert != NULL )
420 return getAlgorithmDescription(&(m_pCert->signature));
422 else
424 return OUString() ;
428 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getSHA1Thumbprint()
429 throw ( ::com::sun::star::uno::RuntimeException)
431 return getThumbprint(m_pCert, SEC_OID_SHA1);
434 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getMD5Thumbprint()
435 throw ( ::com::sun::star::uno::RuntimeException)
437 return getThumbprint(m_pCert, SEC_OID_MD5);
440 sal_Int32 SAL_CALL X509Certificate_NssImpl::getCertificateUsage( )
441 throw ( ::com::sun::star::uno::RuntimeException)
443 SECStatus rv;
444 SECItem tmpitem;
445 sal_Int32 usage;
447 rv = CERT_FindKeyUsageExtension(m_pCert, &tmpitem);
448 if ( rv == SECSuccess )
450 usage = tmpitem.data[0];
451 PORT_Free(tmpitem.data);
452 tmpitem.data = NULL;
454 else
456 usage = KU_ALL;
460 * to make the nss implementation compatible with MSCrypto,
461 * the following usage is ignored
464 if ( CERT_GovtApprovedBitSet(m_pCert) )
466 usage |= KU_NS_GOVT_APPROVED;
470 return usage;
473 // MM : end