05.02.2006 19:22:29Как правильно добавить расширение Basic Constraints? Ответов: 4
tranquilla
Здравствуйте!
Моя проблема вот в чем:
пытаюсь добавить расширение Basic Constraints в сертификат следующим образом (Delphi)
certExtension:CERT_EXTENSION;
extension_blob:PBYTE;
extension_blob_len:DWORD;
basic_constraint:CERT_BASIC_CONSTRAINTS_INFO;

subj_type:PByte;
subj_type_len:DWORD;
ex_blob:CRYPT_BIT_BLOB;
mm:byte;

mm:=$80;
basic_constraint.SubjectType.cbData:=1;
basic_constraint.SubjectType.pbData=@mm;
basic_constraint.SubjectType.cUnusedBits:=0;
basic_constraint.fPathLenConstraint:=true;
basic_constraint.dwPathLenConstraint:=3;
basic_constraint.cSubtreesConstraint:=0;
basic_constraint.rgSubtreesConstraint:=nil;

CryptEncodeObject(encType,szOID_BASIC_CONSTRAINTS,@basic_constraint,nil,@extension_blob_len);
GetMem(extension_blob,extension_blob_len);
CryptEncodeObject(encType,szOID_BASIC_CONSTRAINTS,@basic_constraint,extension_blob,@extension_blob_len);
ertExtension.pszObjId:=szOID_BASIC_CONSTRAINTS;
certExtension.fCritical:=false;
certExtension.Value.cbData:=extension_blob_len;
certExtension.Value.pbData:=extension_blob;

certInfo.cExtension:=1;
certInfo.rgExtension:=@certExtension;
В результате получается неправильный формат сертификата. Есть подозрение,что неправильно заполняю структуру CERT_BASIC_CONSTRAINTS_INFO..А может и нет. В чем может быть ошибка?


 
Ответы:
06.02.2006 11:27:45Kirill Sobolev
На первый взгляд все правильно, т.е. в этом куске кода ошибок нет. Мб ошибка появляется дальше, при кодировании всего остального? А если убрать кусок с Basic Constraints, то работает?
07.02.2006 20:10:22tranquilla
Нет, не работает.. Но:
была попытка осуществить сие следующим образом:
{
basic_constraint:CERT_BASIC_CONSTRAINTS2_INFO;}
basic_constraint.fCA:=true;
basic_constraint.fPathLenConstraint:=true;
basic_constraint.dwPathLenConstraint:=3;
certExtension.pszObjId:=szOID_BASIC_CONSTRAINTS2;
certExtension.fCritical:=false;
certExtension.Value.cbData:=1;
certExtension.Value.pbData:=@basic_constraint;

certInfo.cExtension:=1;
certInfo.rgExtension:=@certExtension;
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,nil,@encCertLen);
GetMem(encCert, encCertLen);
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,encCert,@encCertLen);
В таком виде ОС сертификат распознает, правильно распознает тип дополнения, но неправильно интерпретирует то, что в pbDatа указано...Когда начинаешь структуру эту (basic_constraint) кодировать функцией CryptEncodeObject сертификат системой распознаваться перестает вообще...Такой вот странный глюк...Может как-нибудь по-другому можно сертификат УЦ отличать?
08.02.2006 10:08:04Kirill Sobolev
Нет, обязательно должен быть флаг fCA:=true;
Кодировать в ASN тоже обязательно.
Попробуйте это совместить:

{
basic_constraint:CERT_BASIC_CONSTRAINTS2_INFO;}
basic_constraint.fCA:=true;
basic_constraint.fPathLenConstraint:=true;
basic_constraint.dwPathLenConstraint:=3;
certExtension.pszObjId:=szOID_BASIC_CONSTRAINTS2;
certExtension.fCritical:=false;
CryptEncodeObjectEx(encType,szOID_BASIC_CONSTRAINTS2,@basic_constraint,CRYPT_ENCODE_ALLOC_FLAG, NULL, @certExtension.Value.pbData, @certExtension.Value.cbData);
certInfo.cExtension:=1;
certInfo.rgExtension:=@certExtension;
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,nil,@encCertLen);
GetMem(encCert, encCertLen);
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,encCert,@encCertLen);

08.02.2006 11:48:24tranquilla
Функция CryptEncodeObjectEx не пожелала... В подключаемом модуле прототип не описан.. :(
Заработало вот в таком виде:
basic_constraint.fCA:=true;
basic_constraint.fPathLenConstraint:=true;
basic_constraint.dwPathLenConstraint:=3;
certExtension.pszObjId:=szOID_BASIC_CONSTRAINTS2;
certExtension.fCritical:=false;
CryptEncodeObject(encType,szOID_BASIC_CONSTRAINTS2,@basic_constraint,nil, @certExtension.Value.cbData);
GetMem(certExtension.Value.pbData,certExtension.Value.cbData);
CryptEncodeObject(encType,szOID_BASIC_CONSTRAINTS2,@basic_constraint,certExtension.Value.pbData, @certExtension.Value.cbData);
certInfo.cExtension:=1;
certInfo.rgExtension:=@certExtension;
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,nil,@encCertLen);
GetMem(encCert, encCertLen);
CryptSignAndEncodeCertificate (prov, AT_SIGNATURE, encType, X509_CERT_TO_BE_SIGNED, @certInfo, @(certInfo.SignatureAlgorithm),nil,encCert,@encCertLen);
Что интересно, был практически такой же вариант: единственное различие в том, что certExtension.Value.pbData и certExtension.Value.cbData возвращались в отдельную переменную, а потом записывались в структуру...Не работало :)
Спасибо за помощь!