1 
2 /* ****************************************************************************
3 
4  * eID Middleware Project.
5  * Copyright (C) 2008-2010 FedICT.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License version
9  * 3.0 as published by the Free Software Foundation.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this software; if not, see
18  * http://www.gnu.org/licenses/.
19 
20 **************************************************************************** */
21 #include <iostream>
22 #include <map>
23 #include <array>
24 #include "pkcs15.h"
25 #include "pkcs15parser.h"
26 #include "card.h"
27 
28 namespace eIDMW
29 {
30 
31 	const static tCert CertInvalid = { false, "", 0, 0, 0, 0, false, false, "" };
32 
33 	const static tPrivKey KeyAuthBeidV11 = { true, "Authentication", 0, 2, 4,   130, 128, RSA };
34 	const static tPrivKey KeySignBeidV11 = { true, "Signature",      1, 3, 512, 131, 128, RSA };
35 	const static tPrivKey KeyAuthBeidV17 = { true, "Authentication", 0, 2, 4,   130, 256, RSA };
36 	const static tPrivKey KeySignBeidV17 = { true, "Signature",      1, 3, 512, 131, 256, RSA };
37 	const static tPrivKey KeyAuthBeidV18 = { true, "Authentication", 0, 2, 4,   130, 48,  EC };
38 	const static tPrivKey KeySignBeidV18 = { true, "Signature",      1, 3, 512, 131, 48,  EC };
39 	const static tPrivKey PrivKeyInvalid = { false, "", 0, 0, 0, 0, 0, RSA };
40 	std::map<unsigned char, std::array<tPrivKey, 2> > keymap;
41 
42 	const std::string defaultEFTokenInfo = "3F00DF005032";
43 
44 	const std::string AODFPath = "3F00DF005034";
45 	const std::string PrKDFPath = "3F00DF005035";
46 	const std::string CDFPath = "3F00DF005037";
47 
CPKCS15(void)48 	CPKCS15::CPKCS15(void) :m_poParser(NULL), m_poCard(NULL)
49 	{
50 		if(keymap.empty()) {
51 			std::array<tPrivKey, 2> v11;
52 			v11[0] = KeyAuthBeidV11;
53 			v11[1] = KeySignBeidV11;
54 			keymap[0x01] = v11;
55 			std::array<tPrivKey, 2> v17;
56 			v17[0] = KeyAuthBeidV17;
57 			v17[1] = KeySignBeidV17;
58 			keymap[0x17] = v17;
59 			std::array<tPrivKey, 2> v18;
60 			v18[0] = KeyAuthBeidV18;
61 			v18[1] = KeySignBeidV18;
62 			keymap[0x18] = v18;
63 		}
64 		Clear();
65 	}
66 
~CPKCS15(void)67 	CPKCS15::~CPKCS15(void)
68 	{
69 	}
70 
Clear(CCard * poCard)71 	void CPKCS15::Clear(CCard *poCard)
72 	{
73 		m_poCard = poCard;
74 
75 		// clear everything
76 		//m_csSerial = "";
77 		//m_csLabel = "";
78 
79 		m_oPins.clear();
80 		m_oCertificates.clear();
81 
82 		m_xPin.setDefault();
83 		m_xPrKey.setDefault();
84 		m_xCert.setDefault();
85 
86 		m_xAODF.setDefault(AODFPath);
87 		m_xCDF.setDefault(CDFPath);
88 		m_xPrKDF.setDefault(PrKDFPath);
89 	}
90 
SetCard(CCard * poCard)91 	void CPKCS15::SetCard(CCard *poCard)
92 	{
93 		m_poCard = poCard;
94 	}
95 
96 	//serial number is already retrieved by Get Card Data in the CCard constructor: m_oCardData = SendAPDU(0x80, 0xE4, 0x00, 0x00, 0x1C);
97 /*	std::string CPKCS15::GetSerialNr()
98 	{
99 		if (m_csSerial == "")
100 		{
101 #ifdef VERBOSE
102 			std::cerr << "CPKCS15::GetSerialNr" << std::endl;
103 #endif
104 			if (!m_xTokenInfo.isRead) ReadLevel2(TOKENINFO);
105 		}
106 
107 		return m_csSerial;
108 	}*/
109 
110 	//this is the applet label "BELPIC", hardcoded now
111 /*	std::string CPKCS15::GetCardLabel()
112 	{
113 		// check if we know it already
114 		if (m_csLabel == "") {
115 			if (!m_xTokenInfo.isRead) ReadLevel2(TOKENINFO);
116 		}
117 		return m_csLabel;
118 	}
119 */
120 
CertCount()121 	unsigned long CPKCS15::CertCount()
122 	{
123 		if (!m_xCDF.isRead) ReadLevel3(CDF);
124 		return (unsigned long)m_oCertificates.size();
125 	}
126 
GetCert(unsigned long ulIndex)127 	tCert CPKCS15::GetCert(unsigned long ulIndex)
128 	{
129 		if (!m_xCDF.isRead) ReadLevel3(CDF);
130 		if (ulIndex >= m_oCertificates.size())
131 			throw CMWEXCEPTION(EIDMW_ERR_PARAM_RANGE);
132 		return m_oCertificates.at(ulIndex);
133 	}
134 
GetCertByID(unsigned long ulID)135 	tCert CPKCS15::GetCertByID(unsigned long ulID)
136 	{
137 		if (!m_xCDF.isRead) ReadLevel3(CDF);
138 		for (std::vector<tCert>::const_iterator ic = m_oCertificates.begin();
139 			ic != m_oCertificates.end(); ++ic) {
140 			if (ic->ulID == ulID) return *ic;
141 		}
142 		return CertInvalid;
143 	}
144 
145 
PrivKeyCount()146 	unsigned long CPKCS15::PrivKeyCount()
147 	{
148 		return (unsigned long)(keymap[m_poCard->GetAppletVersion()].size());
149 	}
150 
GetPrivKey(unsigned long ulIndex)151 	tPrivKey CPKCS15::GetPrivKey(unsigned long ulIndex)
152 	{
153 		if(keymap.find(m_poCard->GetAppletVersion()) != keymap.end()) {
154 			return keymap[m_poCard->GetAppletVersion()][ulIndex];
155 		}
156 		return PrivKeyInvalid;
157 	}
158 
GetPrivKeyByID(unsigned long ulID)159 	tPrivKey CPKCS15::GetPrivKeyByID(unsigned long ulID)
160 	{
161 		unsigned char vers = m_poCard->GetAppletVersion();
162 		for (std::array<tPrivKey, 2>::const_iterator ik = keymap[vers].begin();
163 			ik != keymap[vers].end(); ++ik) {
164 			if (ik->ulID == ulID) return *ik;
165 		}
166 		return PrivKeyInvalid;
167 	}
168 
ReadLevel3(tPKCSFileName name)169 	void CPKCS15::ReadLevel3(tPKCSFileName name) {
170 
171 		switch (name) {
172 		case CDF:
173 			ReadFile(&m_xCDF, 2);
174 			// parse
175 			m_oCertificates = m_poParser->ParseCdf(m_xCDF.byteArray);
176 			break;
177 		default:
178 			// error: this method can only be called with CDF or PRKDF
179 			return;
180 		}
181 	}
182 
ReadFile(tPKCSFile * pFile,int upperLevel)183 	void CPKCS15::ReadFile(tPKCSFile* pFile, int upperLevel) {
184 		if (pFile->path == "") {
185 			//path should be set
186 			return;
187 		}
188 		pFile->byteArray = m_poCard->ReadFile(pFile->path);
189 		pFile->isRead = true;
190 	}
191 
192 }
193