Class: GuardTime
- Inherits:
-
Object
- Object
- GuardTime
- Defined in:
- ext/guardtime.c
Constant Summary collapse
- PUBLIC_KEY_SIGNATURE_PRESENT =
The PKI signature was present in the signature.
INT2NUM(GT_PUBLIC_KEY_SIGNATURE_PRESENT)
- PUBLICATION_REFERENCE_PRESENT =
Publication references (list of newspaper etc sources to verify publication value) are present in the signature.
INT2NUM(GT_PUBLICATION_REFERENCE_PRESENT)
- DOCUMENT_HASH_CHECKED =
The signature was checked against the document hash.
INT2NUM(GT_DOCUMENT_HASH_CHECKED)
- PUBLICATION_CHECKED =
The signature was checked against the publication data.
INT2NUM(GT_PUBLICATION_CHECKED)
- NO_FAILURES =
The verification completed successfully.
INT2NUM(GT_NO_FAILURES)
- SYNTACTIC_CHECK_FAILURE =
The level bytes inside the hash chains are improperly ordered.
INT2NUM(GT_SYNTACTIC_CHECK_FAILURE)
- HASHCHAIN_VERIFICATION_FAILURE =
The hash chain computation result does not match the publication imprint.
INT2NUM(GT_HASHCHAIN_VERIFICATION_FAILURE)
- PUBLIC_KEY_SIGNATURE_FAILURE =
The
signed_data
structure is incorrectly composed, i.e. wrong data is signed or the signature does not match with the public key in the timestamp. INT2NUM(GT_PUBLIC_KEY_SIGNATURE_FAILURE)
- NOT_VALID_PUBLIC_KEY_FAILURE =
Public key of signature token is not found among trusted ones in publications file.
INT2NUM(GT_NOT_VALID_PUBLIC_KEY_FAILURE)
- WRONG_DOCUMENT_FAILURE =
Timestamp does not match with the document it is claimed to belong to.
INT2NUM(GT_WRONG_DOCUMENT_FAILURE)
- NOT_VALID_PUBLICATION =
The publications file is inconsistent with the corresponding data in timestamp - publication identifiers do not match or published hash values do not match.
INT2NUM(GT_NOT_VALID_PUBLICATION)
Class Method Summary collapse
-
.gethashalg(signature) ⇒ Object
-
Args : -
signature
-> String containing Guardtime signature token * Returns : - String with OpenSSL style hash algorithm name used for hashing the signed data.
-
-
.getnewdigester(signature) ⇒ instance_of_Digest
-
Args : -
signature
-> String containing Guardtime signature token * Returns : - instantiated object of Digest::…
-
Instance Method Summary collapse
-
#extend(sig) ⇒ Object
-
Args : -
sig
-> String containing binary data with Guardime signature token.
-
-
#initialize(*args) ⇒ Object
constructor
-
Args : -
confighash
-> Optional Hash containing configuration parameters.
-
-
#sign(*args) ⇒ Object
-
Args : -
Digest
-> Digest object, implementing supported hahs algorithm, encapsulating already calculated hash value.
-
-
#verify(*args) ⇒ Object
-
Args : -
sig
-> String containing binary data with Guardime signature token.
-
Constructor Details
#- ⇒ Object #new(confighash) ⇒ Object
-
Args :
-
confighash
-> Optional Hash containing configuration parameters. Defaults:
{ :signeruri => 'http://verifier.guardtime.net/gt-extendingservice', :verifieruri => 'http://verifier.guardtime.net/gt-extendingservice', :publicationsuri => 'http://verify.guardtime.com/gt-controlpublications.bin', :loadpubs => 'auto' }
-
-
Notes :
-
If
:verifieruri
is blank String then online verification is not used. -
:loadpubs
may be eitheronce
-
Publications file is loaded once.
always
-
Publications file is reloaded at each verification call
no
-
Publications file is not used for verification. May be good as token consistency check, or with extra verification (e.g. manual publication string check)
auto
-
Publications file is automatically reloaded if older than 8 hours. Default.
-
Please use environment to specify proxy (syntax), Internet Explorer settints will be used on Windows. Specify url as http://name:pass@site/url for basic auth.
-
771 772 773 774 775 776 777 778 779 |
# File 'ext/guardtime.c', line 771
static VALUE
guardtime_initialize(int argc, VALUE *argv, VALUE obj)
{
VALUE arghash;
if (rb_scan_args(argc, argv, "01", &arghash) == 1)
rb_hash_foreach(arghash, each_conf_param, obj);
return obj;
}
|
Class Method Details
.gethashalg(signature) ⇒ Object
-
Args :
-
signature
-> String containing Guardtime signature token
-
-
Returns :
-
String with OpenSSL style hash algorithm name used for hashing the signed data.
-
-
Raises :
-
TypeError
-> wrong argument datatype. -
RuntimeError
-> other errors like corrupted token etc.
-
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'ext/guardtime.c', line 640
static VALUE
guardtime_gethashalg(VALUE self, VALUE tsdata)
{
int res;
int alg;
GTTimestamp *ts;
StringValue(tsdata);
res = GTTimestamp_DERDecode(RSTRING_PTR(tsdata), RSTRING_LEN(tsdata), &ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
res = GTTimestamp_getAlgorithm(ts, &alg);
GTTimestamp_free(ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
switch(alg) {
case GT_HASHALG_SHA256:
return rb_str_new2("SHA256");
case GT_HASHALG_SHA1:
return rb_str_new2("SHA1");
case GT_HASHALG_RIPEMD160:
return rb_str_new2("RIPEMD160");
case GT_HASHALG_SHA224:
return rb_str_new2("SHA224");
case GT_HASHALG_SHA384:
return rb_str_new2("SHA384");
case GT_HASHALG_SHA512:
return rb_str_new2("SHA512");
default:
rb_raise(rb_eRuntimeError, "Unknown hash algorithm ID");
}
return Qnil;
}
|
.getnewdigester(signature) ⇒ instance_of_Digest
-
Args :
-
signature
-> String containing Guardtime signature token
-
-
Returns :
-
instantiated object of Digest::… implementing exactly same hashing algorithm used for hashing the original signed data.
-
-
Raises :
-
TypeError
-> wrong argument datatype. -
RuntimeError
-> other errors like corrupted token etc.
-
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'ext/guardtime.c', line 577
static VALUE
guardtime_getnewdigester(VALUE self, VALUE tsdata)
{
int res;
int alg;
GTTimestamp *ts;
VALUE module_klass, args[1];
StringValue(tsdata);
res = GTTimestamp_DERDecode(RSTRING_PTR(tsdata), RSTRING_LEN(tsdata), &ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
res = GTTimestamp_getAlgorithm(ts, &alg);
GTTimestamp_free(ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
// checkifnecessary: rb_requre('digest');
module_klass = rb_const_get(rb_cObject, rb_intern("Digest"));
switch(alg) {
case GT_HASHALG_SHA256:
args[0] = INT2FIX(256);
return rb_class_new_instance(1, args,
rb_const_get(module_klass, rb_intern("SHA2")));
case GT_HASHALG_SHA1:
return rb_class_new_instance(0, NULL,
rb_const_get(module_klass, rb_intern("SHA1")));
case GT_HASHALG_RIPEMD160:
return rb_class_new_instance(0, NULL,
rb_const_get(module_klass, rb_intern("RMD160")));
case GT_HASHALG_SHA224:
args[0] = INT2FIX(224);
return rb_class_new_instance(1, args,
rb_const_get(module_klass, rb_intern("SHA2")));
case GT_HASHALG_SHA384:
args[0] = INT2FIX(384);
return rb_class_new_instance(1, args,
rb_const_get(module_klass, rb_intern("SHA2")));
case GT_HASHALG_SHA512:
args[0] = INT2FIX(512);
return rb_class_new_instance(1, args,
rb_const_get(module_klass, rb_intern("SHA2")));
default:
rb_raise(rb_eRuntimeError, "%s", "Unknown hash algorithm ID");
}
return Qnil;
}
|
Instance Method Details
#extend(sig) ⇒ Object
-
Args :
-
sig
-> String containing binary data with Guardime signature token. May be directly loaded from file.
-
-
Returns :
-
String containing binary data with Guardime signature token. May be directly saved etc.
-
-
Raises :
-
ArgumentError
-> if any value is nil or wrong type. -
RuntimeError
-> other errors, including network, hash value, token too new or old etc. Proper description is in the error message.
-
Extended signature token may be used for ‘independent’ verification without any keys or services. Just data, token and newspaper with published value. There is no point in extending new signature before next newspaper publication is performed. Good rule of thumb is to wait for 35 days (after signing), or until 15th date plus 5 more days.
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'ext/guardtime.c', line 298
static VALUE
guardtime_extend(VALUE obj, VALUE in)
{
int res;
GTTimestamp *ts, *ts2;
unsigned char *data;
size_t data_length;
GuardTimeData *gt;
VALUE result;
StringValue(in);
Data_Get_Struct(obj, GuardTimeData, gt);
res = GTTimestamp_DERDecode(RSTRING_PTR(in),
RSTRING_LEN(in), &ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
res = GTHTTP_extendTimestamp(ts, gt->verifieruri, &ts2);
GTTimestamp_free(ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GTHTTP_getErrorString(res));
res = GTTimestamp_getDEREncoded(ts2, &data, &data_length);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
result = rb_str_new((char*)data, data_length);
GT_free(data);
return result;
}
|
#sign(Digest) ⇒ Object #sign(hashalgname, binarydigest) ⇒ Object
-
Args :
-
Digest
-> Digest object, implementing supported hahs algorithm, encapsulating already calculated hash value.
-
example: guardtime.sign(Digest.SHA2.new(256).update(‘this string shall be signed’))
- +hashalgname+ -> String with OpenSSL style hash algorithm name, either SHA256, SHA224, SHA384, SHA512, SHA1 or RIPEMD160.
- +binarydigest+ -> String with binary hash value.
-
Returns :
-
String containing binary data with Guardime signature token. May be directly saved etc.
-
-
Raises :
-
ArgumentError
-> if any value is nil or wrong type. -
RuntimeError
-> other errors, including network, hash value etc.
-
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'ext/guardtime.c', line 251
static VALUE
guardtime_sign(int argc, VALUE *argv, VALUE obj)
{
int res;
GTDataHash dh;
GTTimestamp *ts;
unsigned char *data;
size_t data_length;
GuardTimeData *gt;
VALUE hash, hash2, result;
switch (rb_scan_args(argc, argv, "11", &hash, &hash2)) {
case 1:
get_gtdatahash(hash, &dh);
break;
case 2:
get_gtdatahash2(hash, hash2, &dh);
break;
}
Data_Get_Struct(obj, GuardTimeData, gt);
res = GTHTTP_createTimestampHash(&dh, gt->signeruri, &ts);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GTHTTP_getErrorString(res));
res = GTTimestamp_getDEREncoded(ts, &data, &data_length);
if (res != GT_OK)
rb_raise(rb_eRuntimeError, "%s", GT_getErrorString(res));
GTTimestamp_free(ts);
result = rb_str_new((char*)data, data_length);
GT_free(data);
return result;
}
|
#verify(sig) ⇒ Object #verify(sig, Digest) ⇒ Object #verify(sig, hashalgname, binarydigest) ⇒ Object #verify(sig, ...) {|resulthash| ... } ⇒ Object
-
Args :
-
sig
-> String containing binary data with Guardime signature token. May be directly loaded from file. -
Digest
-> Digest object, implementing supported hash algorithm, encapsulating already calculated hash value. -
hashalgname
-> String with OpenSSL style hash algorithm name, either SHA256, SHA224, SHA384, SHA512, SHA1 or RIPEMD160. -
binarydigest
-> String with binary hash value. Obtain withDigest.digest
for example. -
code_block
-> Optional code block serves two purposes: 1) Allows to implement verification_policies, i.e. add additional checks to the signature verification, and 2) Gives access to signature properties present in code block argumentresulthash
.
-
-
Returns :
-
either
true
orfalse
, depending on the result of verification. If code block is used then the value returned by last statement of code block is passed through.
-
-
Raises :
-
ArgumentError
-> if any value is nil or wrong type, or signature token is corrupted. -
RuntimeError
-> other errors, including network, hash value etc.
-
Code block receives parameter resulthash
which is populated with verified signature properties. There are following keys: verification_errors:: bitfield containing verification errors. See class constants. Verification is successful only if value equals to GuardTime::NO_FAILURES
verification_status:: Numeric bitfield – flags identifying successful verification checks. See class constants. time:: Time object containing signing (time-stamp) datum. registered_time:: Numeric containing ‘time_t’ representation (seconds since Epoch) of the signing datum. hash_algorithm:: String with OpenSSL style hash algorithm name; this algorithm was used for hashing the original data. hash_value:: Hash of the signed data, formatted as String of ‘:’-separated hex octets. location_name:: String containing signature issuer name within the GuardTime network. Example: ‘GT : GT : Customer’ location_id:: String containing ‘.’ separated customer address hierarchy. policy:: String with signing/time-stamping policy OID. publication_identifier:: Publication ID, Numeric. publication_string:: Control string for verifying the timestamp using a hardcopy publication, the value is base32(time+alg+hash+crc32) pub_reference_list:: Array of UTF-8 encoded Strings containing list of newspaper issues or other media used for publishing verification values. publication_time:: Time object containing datum of publishing time which could be used for intependent ‘newspaper based’ verification. public_key_fingerprint:: String with PKI key fingerprint which could be used for extra verification until newspaper hash-link publication becomes available. List of trusted keys is published with publications file.
-
Notes
-
hash algorithm must match one used for hashing the original data during signing. See example below.
-
finish the code block with
resulthash[:verification_errors] == GuardTime::NO_FAILURES
if You care of the return value!
-
-
Examples
-
Default behaviour (without code block) is acheved with following code:
result = guardtime_obj.verify(token) do |resulthash|
-
resulthash == GuardTime::NO_FAILURES
end
- Verification flow with loading token, determining hash alg., hashing file, verifying with signer ID check.
token = slurpbinaryfile('importantdata.txt.gtts')
hasher = GuardTime.getnewdigester(token)
hasher << slurpbinaryfile('importantdata.txt')
gt = GuardTime.new
signedAt = nil
okay = gt.verify(token, hasher) do |r|
signedAt = r[:time]
/companyname$/ =~ r[:location_name] and
r == GuardTime::NO_FAILURES
end
puts "data signed at #{signedAt.utc.to_s}" if okay
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
# File 'ext/guardtime.c', line 482
static VALUE
guardtime_verify(int argc, VALUE *argv, VALUE obj)
{
int res, argcount;
GTTimestamp *ts;
GTDataHash dh;
GuardTimeData *gt;
VALUE tsdata, hash, hash2, block, retval;
GTVerificationInfo *verification_info = NULL;
Data_Get_Struct(obj, GuardTimeData, gt);
argcount = rb_scan_args(argc, argv, "12&", &tsdata, &hash, &hash2, &block);
StringValue(tsdata);
res = GTTimestamp_DERDecode(RSTRING_PTR(tsdata),
RSTRING_LEN(tsdata), &ts);
if (res != GT_OK)
rb_raise(rb_eArgError, "%s", GT_getErrorString(res));
loadpubs(obj);
switch (argcount) {
case 1:
res = verifyTimestamp(ts, NULL, gt, RTEST(block)? 1:0, &verification_info);
break;
case 2:
get_gtdatahash(hash, &dh);
res = verifyTimestamp(ts, &dh, gt, RTEST(block)? 1:0, &verification_info);
break;
case 3:
get_gtdatahash2(hash, hash2, &dh);
res = verifyTimestamp(ts, &dh, gt, RTEST(block)? 1:0, &verification_info);
break;
}
if (res != GT_OK) {
GTTimestamp_free(ts);
rb_raise(rb_eRuntimeError, "%s", GTHTTP_getErrorString(res));
}
#define RBNILSTR(n, i) \
( rb_hash_aset(retval, ID2SYM(rb_intern(n)), (i) == NULL ? Qnil : rb_str_new2(i)) )
#define RBSET(n, v) \
( rb_hash_aset(retval, ID2SYM(rb_intern(n)), (v)) )
if (RTEST(block)) {
retval = rb_hash_new();
RBSET("verification_status", INT2FIX( verification_info->verification_status ));
RBSET("verification_errors", INT2FIX( verification_info->verification_errors ));
// impl
RBSET("registered_time", ULL2NUM( verification_info->implicit_data->registered_time ));
RBSET("location_id", format_location_id( verification_info->implicit_data->location_id ));
RBNILSTR("location_name", verification_info->implicit_data->location_name );
RBNILSTR("public_key_fingerprint", verification_info->implicit_data->public_key_fingerprint );
RBNILSTR("publication_string", verification_info->implicit_data->publication_string );
// expl
RBNILSTR("policy", verification_info->explicit_data->policy);
RBSET("hash_algorithm", format_hash_algorithm( verification_info->explicit_data->hash_algorithm ));
RBNILSTR("hash_value", verification_info->explicit_data->hash_value );
RBSET("publication_identifier", ULL2NUM( verification_info->explicit_data->publication_identifier ));
if (verification_info->explicit_data->pub_reference_count > 0) {
int i;
VALUE pubrefs = rb_ary_new2(verification_info->explicit_data->pub_reference_count);
for (i = 0; i < verification_info->explicit_data->pub_reference_count; i++)
rb_ary_push(pubrefs, rb_str_new2( verification_info->explicit_data->pub_reference_list[i] ));
RBSET("pub_reference_list", pubrefs);
} else
RBSET("pub_reference_list", Qnil);
RBSET("time", gttime_to_rubyTime( verification_info->implicit_data->registered_time ));
RBSET("publication_time", gttime_to_rubyTime( verification_info->explicit_data->publication_identifier ));
} else
retval = verification_info->verification_errors == GT_NO_FAILURES ? Qtrue : Qfalse;
GTTimestamp_free(ts);
GTVerificationInfo_free(verification_info);
if (RTEST(block))
return rb_funcall(block, rb_intern("call"), 1, retval);
else
return retval;
}
|