2 * @file sipe-cert-crypto-nss.c
6 * Copyright (C) 2011 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Certificate routines implementation based on NSS.
34 #include "sipe-backend.h"
35 #include "sipe-cert-crypto.h"
37 struct sipe_cert_crypto
{
38 SECKEYPrivateKey
*private;
39 SECKEYPublicKey
*public;
42 struct sipe_cert_crypto
*sipe_cert_crypto_init(void)
44 PK11SlotInfo
*slot
= PK11_GetInternalKeySlot();
47 PK11RSAGenParams rsaParams
;
48 struct sipe_cert_crypto
*ssc
= g_new0(struct sipe_cert_crypto
, 1);
50 /* RSA parameters - should those be configurable? */
51 rsaParams
.keySizeInBits
= 2048;
54 SIPE_DEBUG_INFO_NOFORMAT("sipe_cert_crypto_init: generate key pair, this might take a while...");
55 ssc
->private = PK11_GenerateKeyPair(slot
,
56 CKM_RSA_PKCS_KEY_PAIR_GEN
,
59 PR_FALSE
, /* not permanent */
60 PR_TRUE
, /* sensitive */
63 SIPE_DEBUG_INFO_NOFORMAT("sipe_cert_crypto_init: key pair generated");
68 SIPE_DEBUG_ERROR_NOFORMAT("sipe_cert_crypto_init: key generation failed");
76 void sipe_cert_crypto_free(struct sipe_cert_crypto
*ssc
)
80 SECKEY_DestroyPublicKey(ssc
->public);
82 SECKEY_DestroyPrivateKey(ssc
->private);
87 static gchar
*sign_certreq(CERTCertificateRequest
*certreq
,
88 SECKEYPrivateKey
*private)
90 PRArenaPool
*arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
94 SECItem
*encoding
= SEC_ASN1EncodeItem(arena
,
97 SEC_ASN1_GET(CERT_CertificateRequestTemplate
));
100 SECOidTag signtag
= SEC_GetSignatureAlgorithmOidTag(private->keyType
,
106 if (!SEC_DerSignData(arena
,
113 SIPE_DEBUG_INFO_NOFORMAT("sign_certreq: request signed successfully");
114 base64
= g_base64_encode(raw
.data
, raw
.len
);
117 SIPE_DEBUG_ERROR_NOFORMAT("sign_certreq: signing failed");
120 SIPE_DEBUG_ERROR_NOFORMAT("sign_certreq: can't find signature algorithm");
123 /* all memory allocated from "arena"
124 SECITEM_FreeItem(encoding, PR_TRUE); */
126 SIPE_DEBUG_ERROR_NOFORMAT("sign_certreq: can't ASN.1 encode certreq");
129 PORT_FreeArena(arena
, PR_TRUE
);
131 SIPE_DEBUG_ERROR_NOFORMAT("sign_certreq: can't allocate memory");
137 gchar
*sipe_cert_crypto_request(struct sipe_cert_crypto
*ssc
,
138 const gchar
*subject
)
140 gchar
*base64
= NULL
;
143 if (!ssc
|| !subject
)
146 pkd
= SECKEY_EncodeDERSubjectPublicKeyInfo(ssc
->public);
148 CERTSubjectPublicKeyInfo
*spki
= SECKEY_DecodeDERSubjectPublicKeyInfo(pkd
);
151 gchar
*cn
= g_strdup_printf("CN=%s", subject
);
152 CERTName
*name
= CERT_AsciiToName(cn
);
156 CERTCertificateRequest
*certreq
= CERT_CreateCertificateRequest(name
,
161 base64
= sign_certreq(certreq
, ssc
->private);
162 CERT_DestroyCertificateRequest(certreq
);
164 SIPE_DEBUG_ERROR_NOFORMAT("sipe_cert_crypto_create: certreq creation failed");
167 CERT_DestroyName(name
);
169 SIPE_DEBUG_ERROR_NOFORMAT("sipe_cert_crypto_create: subject name creation failed");
172 SECKEY_DestroySubjectPublicKeyInfo(spki
);
174 SIPE_DEBUG_ERROR_NOFORMAT("sipe_cert_crypto_create: DER decode public key info failed");
177 SECITEM_FreeItem(pkd
, PR_TRUE
);
179 SIPE_DEBUG_ERROR_NOFORMAT("sipe_cert_crypto_create: DER encode failed");
185 void sipe_cert_crypto_destroy(gpointer certificate
)
187 CERT_DestroyCertificate(certificate
);
190 gpointer
sipe_cert_crypto_import(const gchar
*base64
)
192 return(CERT_ConvertAndDecodeCertificate((char *) base64
));